IntroductionThis document is to help an Android developer begin developing applications for bada. It covers important similarities and differences between the two platforms. Please note some features discussed here refer specifically to versions 2.0 and higher of bada.
Target AudienceAny developer who is interested in learning bada development with previous experience from Android should read this document. This document does not discuss the details of programming languages, but assumes a familiarity with Java and C++, the native programming languages used by both Android and bada.
| |
Organization of This Document
This document covers the comparison of:
- Application life cycles
- Programming languages idioms
- Memory management
- Exception handling
Programming model and framework design
Android and bada are both full-featured "smartphone" platforms. They each use sophisticated asynchronous, event-driven programming models. Android strives to achieve a great level of generality and flexibility. For example, Android uses a high-level abstraction called a Content Provider for data access. bada draws on Samsung's years of mobile device experience, and is streamlined by to make the most common mobile design patterns easier to implement, while still retaining the power to address more complex problems. In the case of data access, bada enables direct use of an SQLite database. This illustrates one of the fundamental tradeoffs between Android and bada: Android has greater generality at the cost of higher overhead and more complexity versus bada's streamlined, targeted features with less overhead and complexity (in most cases).
Application Structure
Android has a fairly unique way of building applications using components. What appears to be a single application from a user standpoint might use components from several different packages. A simple application may consist of only a small number of Activities. A complex application can have flows that use Activities, Services, Content Providers and Broadcast Receivers, each of which might come from a different package. The UI of an Android application consists primarily of all the Activities used. Each Activity achieves a specific purpose. For example, in a phone contacts app, one Activity might show a contact list while another enters a new contact. An Android UI is designed to flow between Activities by passing a special type of data bundle, called an Intent, to the Android system. The system takes care of delivering the Intent to start an appropriate new Activity. This is how Android applications typically pass data and move between different parts of an application. Code Sample 1 shows a simple example of one Android Activity bundling data in an Intent and using it to start another Activity; or, in other words, jump to another UI screen.
// Activity EntryList
…
Intent intent = new Intent();
Intent.setClass("com.samsung.android.example", EntryDetail.class);
Intent.putExtra("index", index);
startActivity(intent);
…
// Activity EntryDetail
…
void onCreate(Bundle savedInstanceState) {
…
int index = getIntent().getExtras().getInt("index");
…
}
…
Code Sample 1: An example of using an Intent to both pass data and start another Activity
In bada, the top level UI consists of forms within a single frame. Forms then take on most of the role of an Android Activity. Applications can switch between forms directly by creating a form object, adding it as an element of the frame, and then making it the active form. This works well for simple applications. For something more complex, tracking all the interactions can become cumbersome and lead to unnecessary code duplication. In this case a common solution is to create an element to act as a central dispatcher. The bada SDK comes with many sample applications that show this approach. Usually the dispatcher class is named something like FormManager. bada has a feature analogous to Intents, whereby one class in an application can post a message to another class along with an array of data. With a dispatcher approach, the application posts a message to the dispatcher class in order to switch from one form to another. Only the dispatcher class needs to know the details of all the other forms. The example in Code Sample 2 demonstrates this approach.
// class EntryListForm
…
LinkedList* pData = new LinkedList();
Index* index = new Index(5);
pData->Add( index );
Frame *pFrame = Application::GetInstance()->GetAppFrame()->GetFrame();
FormManager *pFormMgr = static_cast(pFrame->GetControl("FormManager"));
if (pFormMgr) pFormMgr->SendUserEvent(REQUEST_DEATILSFORM, pData);
…
// class FormManager
void FormManager::OnUserEventReceivedN(RequestId requested,
Osp::Base::Collection::IList* pArgs)
{
Frame *pFrame = Application::GetInstance()->GetAppFrame()->GetFrame();
switch(requestId) {
case REQUEST_DETAILSFORM:
if (null != _pPreviousForm) pFrame->RemoveControl(*_pPreviousForm);
Details *pDetails = new Details();
pDetails->Initialize();
pFrame->AddControl(*pDetails);
pFrame->SetCurrentForm(*pDetails);
pFrame->RequestRedraw();
_pPreviousForm = pDetails;
break;
…
}
Code Sample 2: An example of a central dispatcher that switches between forms
Application Life Cycle and Multitasking
Figures 1 and 2 show the application life cycles in Android and bada, respectively. The application life cycles start from tapping the application icon. Both have an initialization stage right after the application is launched. After the application is initialized, the main event loop is ready and will start to handle the user interaction.
There is not much practical difference in application life cycles between Android and bada. The main difference is when the application moves to the background and how the application is terminated by the user or the system.
Figure 1 Android Application life cycle
Figure 2 bada Application life cycle
| Android | bada |
| onCreate() | OnAppInitializing() |
| onPause() | OnBackground() |
| onResume() | OnForeground() |
| onDestroy() | OnAppTerminating() |
Table 1: Correspondence between application state-change notifications
Android can terminate an application at any time if system resources become too scarce. Android uses a priority system for deciding the order in which to kill applications. Because of the way this prioritization works, only the onPause() event handler is guaranteed to be called before an app terminates. Applications must save any persistent data during the onPause() call to avoid loss.
Similarly, in bada, when the memory is low, the system can decide to terminate both bada and base applications running in the background. If there is not enough memory, the bada platform can terminate an application and remove it from the memory even without alerting the user, nor calling the OnAppTerminating() event handler. To avoid losing important application data, you can use the OnAppCheckpointing() event handler to save the application state or context to the application registry or storage. The OnAppCheckpointing() event handler is called in the low memory situations where a background application is likely to be terminated.
To enable full multitasking in bada, you must tell the platform you want it through a setting in your application configuration file – application.xml. You can do it in the IDE shown as Figure 3:
Figure 3 Multitasking Setting in the bada IDE As in Android, best practices for bada recommend the developer release unnecessary resources, such as camera, GPS and network, when the application enters the background. Also, stop heavy operations such as streaming multimedia and graphics drawing. So basically the multitasking can be enabled in bada 2.0 without much modification of your previous source code.
Programming Language Idioms
bada uses a restricted form of C++. In particular, bada does not support exceptions, uses a limited form of multiple inheritance and a two-stage construction model for creating object instances. Android supports a nearly complete form of Java, including exceptions, interfaces and single-step construction.
Exception Handling
Android supports standard Java exception handling. To reduce overhead, bada doesn't use standard C++ exception handling. Instead bada introduces a system type called result. Applications simulate exception handling by checking the value of
result after function calls. For example:
// Logging specific exception messages
result r = E_SUCCESS;
// Add icon list control to the Form
r = AddControl(*pIconList);
if (IsFailed(r))
{
AppLogException("Exception: %s", GetErrorMessage(r));
delete pIconList;
return;
}
Code Sample 3
You can also use
GetLastResult() to get the exception at any point of the application. So you can handle the exception from the function without return value.
Interfaces
Java supports a form of multiple inheritance by allowing a class to extend one other class, but also mark the class as implementing one or more interfaces. A Java interface is essentially a class made up of unimplemented methods only. The model is so heavily used that Java chose to make interfaces a first class element of the language.
To avoid the complexities introduced by full multiple inheritance, bada takes a nearly identical approach. Classes may only inherit from one other class, and one or more classes consisting entirely of pure virtual methods. A C++ class built only of pure virtual methods is equivalent to a Java interface. These classes in the bada framework are even denoted by names starting with a capital "I", to indicate the class acts as an interface declaration. Declaring a class inherits from an interface class in bada is the same as declaring a Java class "implements" a Java interface.
Instantiation versus Two Phase Construction
Because Java supports exception handling, it can also support object creation by direct instantiation. That is, in Java you create an instance of an object using the new operator and a parameterized constructor.
Without exception handling, it is inconvenient to use the "new" construct in C++ and handle constructor failures. Instead, to avoid problems like memory leaks, bada uses a two-phase construction approach with
new operator and
Construct() method. For example, to fully initialize an array in bada, you need to:
ArrayList *array = new ArrayList();
array->Construct();
Code Sample 4
The first construction phase follows the traditional C++ syntax using new operator. The constructor must not perform any initialization that can fail. For example, initializing a field to a constant value is fine, but allocating memory is not. Any initialization steps that can fail should be deferred to the second construction phase (the call to the Construct() method. The result value can then be used to indicate and handle failures and allow proper clean up.
Memory Management
One of the more convenient features of Java is the automatic handling of memory management. With a small amount of caution, a developer can depend on the Java garbage collection mechanism to reclaim space from unused objects. C++ requires a developer to handle all memory allocation explicitly. To understand the implications, it is important to know about bada's "ownership policy".
In bada, the ownership policy is mostly simple. It just follows the conventional C++ memory handling policy: you should free all the memory you created. When ownership responsibility of memory is passed to someone else, the framework indicates this using an "N" postfix. For example, OnBuddiesReceivedN() tells you memory is allocated within this method, and you have to delete it. The code might look like:
void BuddyManager::OnBuddiesReceivedN(RequestId reqId, Osp::Base::Collection::IList* pBuddyList, int pageNo, int countPerPage, int totalPageCount, int totalCount, result r, const Osp::Base::String& errorCode, const Osp::Base::String& errorMsg)
{
…
//clean up memory
pBuddyList->RemoveAll(true);
delete pBuddyList;
}
Code Sample 5
Entry Point
Finally, it's helpful to understand the difference in entry points to an application between Android and bada. With the Android Intent mechanism, an application can be launched via any Activity exposed as public with an intent filter. TO facilitate launching from the desktop, most Android applications have one activity marked via a special intent filter. That activity will be the one executed when an app is launched by pressing on the app icon.
bada applications are simpler. The system always launches a bada application by calling the special function:
int OspMain(int argc, char* pArgv[])
Code Sample 6