Starting 2007 (launch of the venerable iPhone), Smart phones have changed the way we look at mobile communication. The erstwhile ‘mostly voice phone’ device suddenly transformed into a computing device and opened a new world of possibilities for mobile users.
Amazing User Experience (UX), small form factors, coupled with powerful development platforms & mobile broadband availability have opened up a Pandora’s box in terms of how these tiny devices can be used to improve our daily lives with almost as much productivity as a standard laptop PC. With more than 100,000+ (as of Nov 2009) applications on the iPhone and thousands on other competing platforms like Android, Blackberry, J2ME and Windows Mobile, it is apparent that we are living through a revolution; a paradigm shift, where the world is converging to mobiles and related technologies for erstwhile desktop centric applications. As this paradigm shift is occurring a lot of desktop programmers are being thrown into a new world mobile programming. While there are many tools like Rhomobile (www.rhomobile.com ), PhoneGap (www.phonegap.com), LiquidGear (www.liquidgear.com) and iWebkit (www.webkit.com) which try and bridge the gap between desktop and mobile programming, the seasoned mobile programmer will know these tools only scratch the tip of the iceberg and are only applicable for web based non real-time applications. Programming for limited power/resource devices is a much bigger challenge than the desktop environment.
This whitepaper is a general guideline for developers who are taking a leap of faith into the mobile development world, to help them get a head start in terms of selecting the right approach to develop a mobile application. The paper is independent of any specific platform and simply concentrates on bringing out differentiation in applicable programming methodology.
Smartphones have fewer resources when compared to their desktop counterparts. Some of the notable ones are the battery, the screen size, connectivity, bandwidth and memory. In this section of the paper we will introduce several key challenges. The next chapter will address what we, as developers, can do to mitigate these challenges.
Unlike desktops, mobile phones are usually disconnected from a continuous power source. To add to that, batteries have not been able to keep up to speed in terms of technology advancements when compared to those of the chipsets which reside in the phone. In other words while the phone processors and applications got more powerful, the battery that powers both remained quite the same. Any compute operation performed by an application causes this precious resource to deplete. A compute intensive application would quickly eat up the available battery resource and eventually contribute to a degraded user experience and a potential rejection by users. The battery is not only a problem for application developers; often it is one the reason that leads to phone manufacturers having to make compromises on features for a device. For example, one of the primary reasons that Apple does not allow multitasking for 3rd party applications is that doing so will deplete battery resources more. In Apple’s case, the phone features many software enhancements in terms of UI and functionality, which are already taxing to the battery. Adding multitasking capabilities for 3rd party applications would allow developers to create resource hungry applications that are likely drain the battery to unacceptable levels, quickly.
Irrespective of processor advancements, the form factor of these devices is small and the developers are left with a much smaller real estate to deliver their content on. This brings up several visual challenges. Just because a phone has a great web browser does not mean that it will be as convenient to navigate the same content on a phone as it is on a desktop. Therefore, screen size has a direct relationship to User Experience.
Unlike an always-on Ethernet connection via a DSL or Cable router, a mobile application must cater for sporadic connectivity. Even though mobile operators may advertise ‘Always On’ IP connectivity, in reality however, that is rarely true. High-speed train journeys, a visit to the basement or an elevator are all prime examples or when a phone may drop its connection. Connectivity therefore, is a scarce resource that applications need to cater to.
Different wireless access technologies coupled with subscriber service profile determines the bandwidth that would be eventually made available to the user. As developers we must understand that the available bandwidth is typically a function of the network load in a particular geographical area. Further, data consumption associated tariffs are hefty and especially so, while roaming. Although with the introduction of one-tariff plans this is lesser of an issue, however still, there are many subscribers who use data services on pay as you use basis. Therefore, from an application perspective, not only should the application brace for changes in available bandwidth (example, coverage drops from 3G to GPRS), but by design, the application should be architected in a way that data consumption is as less as practically possible without affecting the quality of the service that is being provided by the application. Another key aspect to keep in mind while developing applications is that typically the downlink bandwidth is higher than the uplink bandwidth.
The reason why we have covered memory last is the fact that newer memory architectures being introduced in mobile phone platforms are making it lesser of an issue for the newer generation of devices. However still there are still millions of phones in use today which feature much less memory and as an application for masses we want to develop an application which can run seamlessly on different classes of devices available in the market today.
Operator & OEM Policies
OEMs and Operators usually build differentiation in their offerings by either customizing the phone platform or publishing guidelines for applications. Unless the application is being developed for a specific service provider and a mobile device, developers should be aware of different vendor policies and application development and deployment guidelines which must be adhered to, for the application to be deployed in a particular network or on a particular device.
With these constraints in our mind, there are some key architectural methodologies, which can be adopted to write optimum code for mobile platforms.
1. Optimizing battery life
Be aware of the power management features of the OS
In order to prolong the battery life most of the mobile phone operating systems enter a dormant state in case there is no activity either by the user or from the underlying hardware platform. When the OS is about to enter a dormant state, applications are usually informed and asked for consent to action. The modern day mobile phone operating system features very complex power profiles and include multiple options for power management of audio, network and video components.
A good architecture should exploit these APIs, notifications and services and gel them well into the user experience in a way that it contributes to an elongated battery life. For example, for an audio player application which is playing background music stored locally on the phone, the video and the network components can be put to a dormant state, however, when the same application is playing back video, it prevents the OS from turning off the backlit display for the video component device.
Some other power management tips:
Tradeoff between burning local CPU vs. using the network for compute heavy jobs
Carefully partition the business logic of the application to leverage network-based infrastructure for compute bound jobs. When adopting this strategy, make sure that you do not end up over architecting the solution, as network access 1) might not be ubiquitously available and 2) might consume relatively higher amount of battery if used excessively. However, if the application being designed is a client/server application and the user is expected to have network connectivity a correct architecture can stretch the battery a long way.
Select the right algorithm; go with as much approximation as allowable
Unless an application is processing something critical, as would be a case for a financial application, users are often ok with approximations in display and numbers especially in games and UI components. Higher precision often comes at a higher computation and hence battery costs. This concept is very useful when developing complex user interfaces and games. A good example is a video playback application which can fallback to a lower resolution-rendering engine suitable for the form factor of the device’s screen.
Avoid floating point computations
Almost all of the mobile phone platforms do not feature a floating point co-processor and hence all floating point computations are executed using fixed point libraries which is quite a drag on the CPU and hence the battery. It is advised that either architects develop equivalent fixed-point algorithms or use the strategy laid out in 3.1.2 if such computations cannot be avoided.
Resort to an event driven architecture as application loops prevent the OS from putting the application and hence the device in the low power state. This approach saves a lot of battery and also gels well with the modern mobile phone OS architectures as well, since most of the OSs are designed to enter a dormant state till an event to be serviced occurs on the phone.
Cooperative multi-tasking is an application design pattern where applications willingly give up CPU whenever they don’t need it, to give other tasks in the system a fair share of CPU. Cooperative multi-tasking mixed with event driven programming methodology not only leads to optimal battery performance but
also helps the OS to keep the platform responsive and interactive for other operations that the user might want to perform on the phone. While almost all OSs follow an application development methodology centered on cooperative multi-tasking as a defacto standard, implementation and realization depends on the platform.
Different OSs take different approach towards Multi-threading in general. While in J2ME and Blackberry, it the way to implement multi-tasking, it is not a preferred approach on OSs like Symbian as it introduces un-necessary overhead in the runtime system.
A good architecture should ideally abstract multi-tasking libraries of the OS from the core application code and adapt the abstraction to the platform depending upon the platform.
Use Compiler Optimizations
Applications can often be improved for performance and battery by optimizing the application using available compiler options. Study these options well.
2. Optimizing for Screen and User eXperience (UX)
While developing applications developers should ensure that nothing that they do affects the primary user experience in a negative way. Most of the operating systems today ensure such a behavior. As developers, we must also ensure that we follow the guidelines such that the application user experience integrates well with the native user experience of the phone platform. This will not only ensure that the users adapt well to the application but will also help users get comfortable with the application with little or no coaching. On the technical side, most of the UI components, which are natively supported by the platform, have already been optimized for the platform in addition to being tested for correctness/bugs. Reusing these components will not only reduce the amount of code but also add to stability of your own application. Some of the common guidelines for designing User Interfaces are as follows:
3. Connectivity and Bandwidth
Applications accessing the enterprise, social networking sites, Massively Multiplayer Online (MMO) gaming engines are already taxing the wireless networks. Although data connectivity may be good its availability and the size of the broadband pipe which is available to the subscriber, is largely variable. Hence, if an application needs online connectivity, it would be a good idea to plan for an online and offline mode during design.
In the offline mode the application typically caches data in the local database and makes it available to the user even there is little or no connectivity, and then the data is synchronized with the backend servers as better connectivity or bandwidth is available.
Are online applications better than offline applications? No one strategy is better than the other and shall be chosen by the architects based on its applicability to the problem they are attempting to solve. While the online mode is more secure and allows its users to access most up-to-date data, their main limitation is that such applications are typically slow and unusable when there is little or no coverage. The hybrid approach on the other hand takes care of the offline issue but designing such applications is typically complex and non-trivial and for online gaming engines this approach might not be applicable at all. This approach is slightly less secure as well, since, the data which is cached locally, can fall into wrong hands as the device is stolen or misplaced.
Architect applications so that it can work with the minimal level of data available (i.e. don’t wait till you get the best datasets to work on, and till then process/render the best approximation that is viable for your app for now, since quick display is very important. A good example would be the various mapping applications, which resort to approximations till they download either a better map or derive a more precise location.
Memory footprint of applications is another important aspect, which the developers need to consider while designing a mobile application. Most of the engineers often end-up over-engineering the solution by creating frameworks on top of which the user application is built. While this is a wise approach, often creating generalized frameworks introduces a lot of code, which could have been otherwise avoided, and hence contributes to memory footprint significantly. Care should be taken so as strike the right balance between what should be developed generic and specific for the platform and the application. Here are some tips:
5. Abstract using layers: Code for Diversity / Fragmentation
Unlike in the desktop world, where there are a handful of well knows Operating Systems the mobile world is fraught with fragmentation. Depending on country, operator, device and other factors the same mobile platform is often changed enough to cause nightmares for the developer. There are several causes for fragmentation, including:
Application users, developers, content providers and distributors, network operators and device manufacturers are all affected by fragmentation. While designing applications developers must ensure that the solution architecture is generic enough so that it can be easily adapted to multiple targets. A good approach would be to identify layers, which should be specific to the platform. Once such demarcation has been identified, a large portion of code can be reused across platforms with development effort restricted only to platform specific modules.
6. Performance Optimization
7. Know how to Test
Developers often end up testing applications on device emulators and not target hardware or real devices. This could lead to problems when the solution is actually deployed across different platforms since, there could be notable differences in the emulator and the platform related to the application execution environment, the memory model and the performance parameters.
Several questions plague this community when it comes to testing:
The answer to the above deserves a detailed whitepaper each. Suffice to say, at HSC we have tackled exactly these problems and have designed the right workflows and methodologies to meet such challenges for you.
Model View Controller (MVC) is one of the most used and popular application design patterns today and yet so very few application developers use it in the mobile phone development paradigm for their own applications. The design methodology calls for an architecture, which decouples the rendering (view) from the logic (controller) and data (model) and isolating each of these layers from each other through a well-defined interface. In fact, the MVC architecture is used extensively by modern phone platforms like Android, iPhone etc. In this approach the view depends only on the model to render everything on the screen. The controller receives input, can gain additional information by calling the view, and at the end manipulates the model. The advantages of this architecture are:
Figure 4-1: Model View Controller Solution Design Pattern
In this paper we propose a slightly modified MVC pattern be used in mobile applications. In this proposal, the architecture leverages the fact that most of the mobile applications are single threaded and co-operatively multi-tasked and hence there will be a consistent view of the model for both the controller as well as the view. The additional exchange between the model and the view where the view consumes the model in a read-only mode allows for an optimization where un-necessary parameter marshalling can be avoided and the view can retrieve only that data which it needs from the model. The same architecture can also be extended for multi-threaded scenarios. However in that case, care needs to be taken that the consistency of data is maintained across the view and the controller, because the view might retrieve data from the model through a different thread.
Figure 4-2: Customized Application View Controller Design Pattern