the Flagship blog & community for App Developers with main focus on Samsung's bada and cross-platform technologies
Bada Tutorials, Fundamentals

Anatomy of “Hello World” – the bada way

, November 24th, 2009

Any new technology needs a good “Hello World” example, bada shall not be an exemption. From a source I have received a sample “Hello World” app. Here it comes…

First thing you have to be familiar with is the c++ programming language. The example code provided here has been developed on the Visual Studio 2005 platform + bada wizard and tested with the bada simulator. The following files are observed:

  • HelloWorld.h
  • HelloWorld.cpp
  • HelloWorldEntry.cpp

There are also two XML files in the project called application.xml and manifest.xml. Those will not be subject of this post though.

First things first – you need a central class for your application. Let’s start with its header.

HelloWorld.h

#ifndef __HELLOWORLD_H__
#define __HELLOWORLD_H__

#include <FBase.h>
#include <FGraphics.h>;
#include <FLocales.h>
#include <FSystem.h>
#include <FApp.h>

using namespace Osp::Base;
using namespace Osp::Graphics;
using namespace Osp::Locales;
using namespace Osp::System;
using namespace Osp::App;

class HelloWorld :
	public Application // must inherit from Application class
{
public:
	// The application must have a factory method that creates an instance of the application.
	static Application* CreateInstance(void);

public:
	HelloWorld();
	~HelloWorld();

public:
	// The application must provide its name.
	String GetAppName(void) const;

protected:
	// The application must provide its ID.
	AppId GetAppId(void) const;

	AppSecret GetAppSecret(void) const;

public:
	// This method is called when the application is initializing.
	bool OnAppInitializing(AppRegistry& appRegistry);

	// This method is called when the application is terminating.
	bool OnAppTerminating(AppRegistry& appRegistry);

	// Thie method is called when the application is brought to the foreground
	void OnForeground(void);

	// This method is called when the application is sent to the background.
	void OnBackground(void);

	// This method is called when the application has little available memory.
	void OnLowMemory(void);

	// This method is called when the device's battery level changes.
	void OnBatteryLevelChanged(BatteryLevel batteryLevel);
};

#endif

Most of the stuff in this header file should be self-explanatory, especially for those of us who work frequently with c++. There are a few things to note though.

There is a bunch of different headers you will want to use in almost any app.  These are, e.g.:

  • Base - basic features and interfaces (especially bada-specific datatypes)
  • Graphics – allows drawing on the screen (note that these are plain low-level drawing operations – User Interface features are in another package called Osp::UI)
  • Locales – for culture-related features/information (e.g. for correct date, currency and number formats)
  • System – For basic system interaction (e.g. alarms, battery levels, etc.)
  • App – allows you to manage your own application and its settings as well as starting and running other apps

The class of your application must inherit from the Application class defined somewhere within the Osp::App namespace. This also assumes that your class must implement some functions, like:

  • A static factory function that returns instances of the application’s class
  • A constructor and a destructor function
  • Some basic information functions that return the name, id or the secret code of your app
  • Some obligatory event handlers that are called on important events like the application start or change in the battery levels.

This is the minimum skeleton of any application you will develop under bada.

The definitions are also straight forward:

HelloWorld.cpp

#include "HelloWorld1.h"

HelloWorld1::HelloWorld()
{
}

HelloWorld1::~HelloWorld()
{
}

Application*
HelloWorld::CreateInstance(void)
{
	// You can create the instance through another constructor.
	return new HelloWorld();
}

String
HelloWorld::GetAppName(void) const
{
	static String appName(L"HelloWorld");
	return appName;
}

AppId
HelloWorld::GetAppId(void) const
{
	static AppId appId(L"93bt1p123e");
	return appId;
}

AppSecret
HelloWorld::GetAppSecret(void) const
{
	static AppSecret appSecret(L"9C645DDBA19C71BAD1204DA4DAA7A0B9");
	return appSecret;
}

bool
HelloWorld::OnAppInitializing(AppRegistry& appRegistry)
{
	// TODO:
	// Initialization including UI construction can be done here.
	// Load the application's latest data, if necessary.
	// If this method is successful, return true; otherwise, return false.
	return true;
}

bool
HelloWorld::OnAppTerminating(AppRegistry& appRegistry)
{
	// TODO:
	// Deallocate or close any resources still alive.
	// Save the application's current states, if applicable.
	// If this method is successful, return true; otherwise, return false.
	return true;
}

void
HelloWorld::OnForeground(void)
{
	result r = E_SUCCESS;

	Canvas* pCanvas = GetAppFrame()->GetCanvasN();
	if(pCanvas == null)
		return;

	Font* pFont = new Font();
	pFont->Construct(FONT_STYLE_PLAIN | FONT_STYLE_BOLD, 50);
	pCanvas->SetFont(*pFont);

	r = pCanvas->DrawText(Point(30, 30), GetAppName());
	if (IsFailed(r))
	{
		AppLog("pCanvas->DrawText() failed.\n");
		delete pCanvas;
		return;
	}

	r = pCanvas->Show();
	if (IsFailed(r))
	{
		AppLog("pCanvas->Show() failed.\n");
		delete pCanvas;
		return;
	}

	delete pCanvas;

}

void
HelloWorld::OnBackground(void)
{
}

void
HelloWorld::OnLowMemory(void)
{
	// TODO:
	// Deallocate as many resources as possible.
}

void
HelloWorld::OnBatteryLevelChanged(BatteryLevel batteryLevel)
{
	// TODO:
	// It is recommended that the application save its data,
	// and terminate itself if the application consumes much battery
}

There is probably nothing to explain here, seems simple and straight to the point. Finally you need an entrance point of the app (like main(…)). This is done in a separate file:

HelloWorldEntry.cpp

/**
* OSP Application entry point(OspMain) introduced.
*/
#include <fapp.h>
#include "HelloWorld.h"

using namespace Osp::Base::Collection;

extern "C"
{
	__declspec(dllexport) void OspMain(int hInstance, int argc, char *argv[]);
}

/**
* Entry function of OSP Application which is called by the operating system.
*/
extern "C" {
void OspMain(int hInstance, int argc, char *argv[])
{
	AppLog("OspMain() Started. \n");

	result r = E_SUCCESS;

	ArrayList* pArgs = new ArrayList();
	pArgs->Construct();
	for (int i = 0; i < argc; i++)
	{
		String* pEachArg = new String(argv[i]);
		pArgs->Add(*pEachArg);
	}

	r = Osp::App::Application::Execute(HelloWorld::CreateInstance, pArgs);
	if (IsFailed(r))
	{
		AppLog("Application execution has failed.\n");
	}

	if (pArgs)
	{
		pArgs->RemoveAll(true);
		delete pArgs;
	}

	AppLog("OspMain() Ended. \n");
}
}

Interesting points to note here. The OspMain(), which is the main entrance point called by the bada OS, has to be exported (made visible/callable by the outside world) through the __declspec(dllexport) call.  Another interesting thing are the arguments passed to the program. I suspect that you can pass some data here if you start an app from another app. These arguments are stored in an ArrayList, one of bada datatypes defined in Osp::Base namespace.

Finally you see where exactly the factory method of HelloWorld class is used to start the execution of the app.

So there it is! :-) I couldn’t test it myself, since I do not have an SDK, so bear with me, if I have made false assumptions somewhere. Nevertheless, I guess this is enough to get a first taste!

Related posts:

  1. Bada sample project: Simple Greeting
  2. Forms Management in Bada (part 3) – Managing Forms
  3. Bada Tutorial: UI Lists (part 2) – Custom List
  1. 12 Responses to “Anatomy of “Hello World” – the bada way”

  2. By Jung Jin Lee on Nov 27, 2009 | Reply

    i think the “bada” seems like a branch of SYMBIAN system.

  3. By question on Dec 8, 2009 | Reply

    A few Things I like to know as an C++ Programmer:

    Why do you NOT use exceptions?
    Why is there no use of smartpointers?
    Is STL supported?
    Is boost supported?
    Do you have anyplans to build a port of Qt Mobility for Bada?

  4. By wit on Dec 9, 2009 | Reply

    question, this source code is not really written by me so I probably won’t be of much help, however…

    As I understand it the exception handling on the bada API is intentionally done by querying the result of a function and then running it through some if/catch statements.

    r = Osp::App::Application::Execute(HelloWorld::CreateInstance, pArgs);
    	    if (IsFailed(r))
    	    {
    	        AppLog("Application execution has failed.\n");
    	    }
    

    For your own code you may be using exceptions (I guess)

    Smart pointers, although pretty elegant if used wisely, are a major source of bugs and I guess they are too heavy for a simple Hello World app.

    STL is said to be supported (but not all of it)

    Can’t answer the rest of your questions :-P

  5. By littledog on Dec 9, 2009 | Reply

    @question Yes there will such nice things developers love in Symbian: nonstandard exception handling, forget about smart pointers, two phase construction. It seems smart pointers are not that smart in small devices.

  6. By Ped on Dec 10, 2009 | Reply

    If the OspMain part preparing/releasing argument list is of similar quality of rest of API/core, then I will rather not touch this piece of SW without some long and heavy pole (to bash it badly).

    To explain:
    1) why it even needs conversion? The data are already stored in memory in reasonable format. Converting them means at least one more duplicate, judging by pArgs->Add(*pEachArg); there may be third one too. This will eat memory for no direct gain (in case somebody *needs* ArrayList, he can do the conversion inside app) and if there’s a way to supply very long arguments, it can under certain circumstances lead to no memory crash, or even exploitable crash.

    2) “new”, “delete”, no exception handling and the puzzling “Add(*pEachArg);” part … I mean, this reminds me of the classic C++ source, the thing I left in past long ago and never turned back. It’s not elegant, it’s not efficient and it’s error prone. Modern C++ source can be soooo much better if used properly.

    Still mobile platform with native C++ sounds very interesting for me, I just hope it’s open enough and the API well defined and well coded. So far I’m not impressed by this tiny piece of code.

  7. By Variadic_Templates on Jan 5, 2010 | Reply

    wit, smart pointers “are a major source of bugs”??!! Like which bugs? And are they worse than the memory leaks inherent in “new” & “delete” code? Exception safety?
    So, we are relegated to choosing between elegant smart pointers & ugly, buggy, error prone, memory-leak-friendly “new” & “delete”? Not much of a choice. Come on Samsung, at least give us bada created smart pointers, albeit NOT the macro kind we had in wxWidgets.

  8. By wit on Jan 6, 2010 | Reply

    Variadic, maybe my wording wasn’t that good :-P

    What I meant was my personal experience, since I did struggle with the smart pointers in the past and caused more damage than good. But this is not the topic here. It was long ago, too.

    What I do know though is that from my experience mobile devices are very limited on resources, Performance is the name of the game here. Sure, smart pointers and try-catch blocks and whatnot are elegent, but they do add overhead.

    I can tell you that.

    Once you have worked a few hundred hours on an app and realize later that it is worthless because the performance is simply unacceptable on a device, then you’ll remember your elegant code :-) Been there, done that :-P

    I have huge respect for those programmers back in the old days when we landed men on the moon. The whole mission systems together were not much more powerful that a mobile phone you’d hold in your hands today. Those were truly genius algorithm-gurus, they had to fight for each single byte of resource.

    I do not say that we should return to assembly, but I do think that one should differentiate between code written for different systems. You do not always have the luxury of nearly limitless resources.

  9. By sihem on Mar 19, 2010 | Reply

    j’arrive pas à compiler “helloword”
    message d’erreur: multiple definition of ‘OspMain’
    s’il vous plait je veux un aide
    merci <3

  10. By wit on Mar 19, 2010 | Reply

    Sihem, what IDE/SDK version do you have? This “Hello World” example is from the earliest pre-alpha version from November 2009. There have been like a dozen “releases” since then and thing did change a lot.

    I remember of having had a similar error in the past, I do not remember what the problem was though.

    Please tell more of what exactly you are doing, you can write in French, too. I understand it a bit :-)

  11. By Suvin on Aug 28, 2010 | Reply

    How to compile this code from Command prompt using Gcc toolchain.

  12. By Koto on Oct 2, 2010 | Reply

    Isn’t it a memory leak ?

    HelloWorld::OnForeground(void)
    {
    Font* pFont = new Font();

    this pFont pointer is not released…

  1. 1 Trackback(s)

  2. Nov 27, 2009: jokka's me2DAY

Post a Comment

Editor's picks

Copyright 2009-2010 BadaDev.com (unless otherwise stated). All rights reserved! Powered by Wordpress!