Apple versus The world

Three days ago Apple published a post by Steve Jobs defending their decision to not allow Flash on their shiny mobile devices (namely the iPhone, iPod and iPad). To sum up, here are the reasons:

  1. Apple’s solution is being more “open” than Adobe.
  2. Missing flash doesn’t hinder the user’s ability to browse and enjoy the web as the world is submitting to Apple’s “innovative” interface.
  3. Flash is a security menace.
  4. Using flash for video would drain battery because there were no hardware decoders.
  5. Flash doesn’t fit in Apple’s touch agenda.
  6. Apple thinks there should not be anything between its operating system (OS) and application so developers could exploit the full potential of the OS.

There has been various long and detailed arguments counter and support Jobs’ view. Mine is below.

No doubt Jobs is very convincing. It’s his job! The article gives you the feeling Apple is the good guy here and they have been benevolent to Adobe so far. Adobe just can’t live without Apple and Apple has been the source of innovations all along.

Really?

While it’s true that Apple had helped Adobe to exit their “proverbial garage”. Apple didn’t get out of it on their own. Say, where did the interface for MacOS came originated? And while Apple is busy praising their “novel” concept of a touch interface, I have been scrolling web pages under the touch of one finger on my p990i for years. To give Apple credit for the touch interface is like giving a wheel rim manufacturer credit for inventing the wheel  while in fact all they did were making golden rims. Should we stop using iron-cast rims when there’s the golden rim? That is a change but not such a big one. Marketing hype did the most part of the job! (Introduction and point 5)

Criticizing Adobe for not publishing Flash as a standard and emphasizing Apple’s role in the creation of HTML5 doesn’t make Jobs look better :/. Who are using the web? The users or some technical manager at Apple? Don’t they deserve a choice on what to view and what not to? Would excluding Flash make their device crash-free? It’s the device we spent our money on, and we don’t have a damn right to crash it? :/ If Flash had crashed that much and is such a big security exploit, why doesn’t Opera, Firefox, Chrome or Safari block it? 😐 (Point 3)

And who forced us to pay to use the proprietary H.264 format by rejecting a free and open alternative? While I would agree that HTML5 is the future, Apple’s conservative stance is making it worse! (Point 1 and 4)

As a developer, I just hate the time when you need to do something a bit advanced on Windows, you have to go online and asks for some hidden API buried in some stupid-named dll. What kind of name is MCEWMDRMNDBootstrap? And how come when I wanted something to run on Linux I have to fork a new code path and recompile it? I’m just glad there were Java! To prohibit flash in favor of MacOS’ API is like prohibiting Java to run on Windows. Imagine that! What is the big idea in this step back? 😐 (Point 1 and 6)

And to say Flash is complex and all content developer should abandon it to produce faster, richer application is like telling all Word (or iWork) users to write documents with notepad and automate with C++! The designer’s job is to design, not to learn objective-C! There are thousands application on the App Store but how about millions of games already there on the internet? Are you absolutely sure that everything the world will ever need is in the App store? (Point 2)

By the way, speaking of the App store has just reminded me of how paranoid Apple is to Google (and to changes). First they rejected Google voice to “ensure a streamlined experience to our users”. Meh, why don’t they just say that their own voice application is trash and they are afraid of competition? 😐 And then they threatened a third party developer for a one-line mention of Google’s Android! Plain drama! (Point 1 again)

In conclusion, from my point of view Apple is not the only mobile manufacturer in the world. We still have a lot of alternative choices, make yours wise. Would you trust your data in the hand of a dictator who won’t even allow you to to have an extra battery for your phone? 😐

First Android application

Or so… if numerous "hello world" applications doesn’t count. Well, time flies, it has been three weeks since the android class I was attending ended. Many thanks to MultiUni for organizing the event! I joined the class simply because of the boldness of whoever bring the idea of a learning community into motion, especially in Vietnam; and I know many share the same feeling with me. It’s a great opportunity to meet more people and get updates on what’s going on. One of my teachers wanted to do this years ago in the form of a university’s computing club but it seems the idea never saw the light of day – he is now a PhD or more accurately, Doctor of Science. He have had more important things to devote his time for 🙂

1.0 A half-user, half-programmer’s rant

Being short doesn’t stop the class from giving me a good head start on Android. Basically the Android’s application share much in common with J2ME, a cousin sharing the same root with Android in the Java family. However, Android have a more clearly defined framework – all naming are done according to convention, similar functions from different packages doesn’t have drastically different names like Java. The Dalvik debugging monitor server (with which you can interact through the DDMS view installed with Android Development Tools) is better integrated into the IDE and easier to use than its J2ME’s counterpart. All rounded up, Android is a fantastic platform to start mobile programming!

But being good doesn’t mean things are automatically going to be great for you. A while back I blogged about how frustrating Symbian programming is and predicted its demise. Well, that came true when the iPhone started to take up market share. Ironically that doesn’t mean I am good at predicting market trends but the exact opposite! Apparently hypes and marketing niches have more to do with the success of a product than technical feasibility.

smartphone_market_share_3Q09_trend

Smartphone market share trends, via Gartner and Arstechnica

The iPhone replaced Symbian’s complex model with an arcane platform! Did you know that you need a Mac to be able to program the iPhone? And while Apple started to dwarf Nokia on the mobile market, the first Android phones started to came out. Even a developer community such as the class I were in have only 3 Android phones and though so, they weren’t used for daily tasks like calling or texting :/

Technology takes time to be adapted, but Android just doesn’t have the "coolness" of the iPhone. You can’t impress your girlfriend telling her "I have the latest Google’s touch screen phone with fancy location based features" – she’ll simply ask "isn’t Google a search engine"?

That being said, the future is not bleak for Android. Google, after all is also a big company; and most importantly, they are driven by innovation in technology, just like Apple is driven by innovation in design and user interface. This is going to be an interesting battle and who knows? Maybe you are picking the winning side right now 😉

2.0 The application

Okay, as the title of this post have stated, it’s not an application that will make you coffee to impress your girl (or guy) but rather a demonstrative application on how easy it is to perform system tasks with Android.

The first objective is to make an application that displays pictures from a list. For simplicity’s sake, this will be an array of URLs; of course this can easily be replaced with an RSS feed. Secondly, when the user selects one of those pictures, the application will save it to the device and set it as the wallpaper.

2.1 Display

According to the instruction given, I should have made an application that displays one picture at a time and three buttons to flip between pages and set the wallpaper, like this:

ui1

But being such a busybody I took a scan on the Android samples that comes with the SDK. Fortunately there’s a gallery application using the ImageSwitcher control that looks substantially better:

android_api_imageswitcher

Besides the look, the ImageSwitcher interface also have a view initializing method, GetView so you can implement your own image generating procedure. This is especially useful for an advanced function: caching images.

public View getView(final int position, View convertView, ViewGroup parent)

ImageSwitcher is not a collection of images but rather a collection of ImageView controls, this allows for greater flexibility: you can customize how each image is rendered. For examples, odd images have a white border and even ones have a black border.

As you may have known, mobile devices have significantly tighter memory limit than full-pledged computing devices. Android phones is not an exception. You can only load like 10 640×480 pictures before hitting an “out of memory” exception. In this application I will cache eight images at a time. The caching algorithm is based on the priority queue principle: any time an image is used (get displayed either as the current image or in the preview line), it is moved to the top of the queue, images at the bottom of the queue are disposed to make room for new ones as necessary.

// 1 for view and 8 for scrolling
private final int cacheThreshold = 8;	
private LinkedList imageCache = new LinkedList();

The cache’s data structure 

It appears that all objects in Android have a Tag attribute so you can attach anything you want to them. I used that to attach the position of the image contained in the ImageView control in the list. By looking at this value you can easily determine when the ImageView is being displayed and move it up the queue.

		public View getView(final int position, View convertView,
				ViewGroup parent) {

			// Search if the cache already have the image,
			// this is better implemented as some kind of
			// comparison operator, but we don't have time
			// to look into that right now

			// Convert the queue to an array for easier iteration
			for (int i = 0; i < imageCache.size(); i++) {
				ImageView temp = imageCache.get(i);
				String imageTag = (String) temp.getTag();
				// Why string and not just position?
				// It will be easier to implement image loading
				// from the file system (images will be referred
				// to by path)
				if (imageTag.compareTo(imageLinks[position]) == 0) {
					// Increase priority for the returned item
					imageCache.remove(i);
					imageCache.addFirst(temp);
					return temp;
				}
			}

			// Load a new image if not cached
			while (imageCache.size() >= cacheThreshold)
			{
				imageCache.getLast().destroyDrawingCache();
				imageCache.removeLast();
			}
			final ImageView newView = new ImageView(mContext);

			newView.setAdjustViewBounds(true);
			newView.setLayoutParams(new Gallery.LayoutParams(
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

			// Load the first image with blocking routine to make sure it will display
			if (firstImage) {
				firstImage = false;
				BitmapInfo mResults = BitmapDownloader
					.downloadBitmap(imageLinks[position]);
				newView.setImageBitmap(mResults.getBitmap());
			}
			else
			{
				// Uses the asynchronous routine for other images
				Thread t = new Thread() {
					public void run() {
	
						BitmapInfo mResults = BitmapDownloader
								.downloadBitmap(imageLinks[position]);
						mResults.setToAssign(newView);
						Message downloadedMessage = new Message();
						downloadedMessage.setTarget(mHandler);
						downloadedMessage.what = MESSAGE_TYPE_WALLPAPER_DOWNLOAD_COMPLETE;
						downloadedMessage.obj = mResults;
						mHandler.sendMessage(downloadedMessage);
					}
				};
				t.start();
			}

			newView.setTag(imageLinks[position]);
			// Add the changed entry back to the cache
			imageCache.addFirst(newView);

			return newView;

		}

		private Context mContext;
		private Handler mHandler = new Handler(new Callback() {

			@Override
			public boolean handleMessage(Message msg) {
				if (msg.what == MESSAGE_TYPE_WALLPAPER_DOWNLOAD_COMPLETE) {
					final BitmapInfo downloaded = (BitmapInfo) msg.obj;
					// Fail? Try again, memory will be freed in a moment...
					if (downloaded.getBitmap() == null) {
						Thread t = new Thread() {
							public void run() {

								BitmapInfo mResults = BitmapDownloader
										.downloadBitmap(downloaded.getIdentifier());
								mResults.setToAssign(downloaded.getToAssign());
								Message downloadedMessage = new Message();
								downloadedMessage.setTarget(mHandler);
								downloadedMessage.what = MESSAGE_TYPE_WALLPAPER_DOWNLOAD_COMPLETE;
								downloadedMessage.obj = mResults;
								mHandler.sendMessage(downloadedMessage);
							}
						};
						t.start();
					}
					else
						downloaded.getToAssign().setImageBitmap(
							downloaded.getBitmap());
				}
				return true;
			}
		});

		// Control first image's loading
		private boolean firstImage = true;
		private static final int MESSAGE_TYPE_WALLPAPER_DOWNLOAD_COMPLETE = 3;

The full caching & downloading routine

The Handler in Android is similar to the action or key press listener in java, it handles messages sent to it and have access to all the private variables inside the object it’s placed in. But unlike Java it’s not bound to the object and one object can have multiple handler. However it’s worth noting that Handler’s processing is blocking and it will halt the thread it’s running on so it’s not a good idea to use them for long activities like data transmission. In this case I:

  1. Send the download request to the Handler
  2. The handles process the download request and creates a new thread to download the image.
  3. When the thread is done, is sends a message back to the Handler. Note that I attached the image to that message using Message.obj
  4. Finally the Handler assigns the downloaded image back into the View

Oh, and accessing the internet requires permission from the user (so you won’t send out sensitive data). To get permission you’ll have to ask for it, add those to the manifest file:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

 

2.2 Set wallpaper

In android, to make a button do something, you set its listener, like this

final Button btnSetWallpaper = (Button) findViewById(R.id.btnsetwallpaper);
		btnSetWallpaper.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// Save dialog
				AlertDialog.Builder builder = new AlertDialog.Builder(arg0
						.getContext());
				builder.setMessage("Do you want to save this image?")
						.setCancelable(false).setPositiveButton("Yes",
								wallpaperDialogHandle).setNegativeButton(
								"Cancel", wallpaperDialogHandle)
						.setNeutralButton("No", wallpaperDialogHandle);
				AlertDialog alert = builder.create();
				alert.show();

			}
		});

And then define what the listener will do:

public DialogInterface.OnClickListener wallpaperDialogHandle = new DialogInterface.OnClickListener() {

		@Override
		public void onClick(DialogInterface dialog, int which) {
			switch (which) {
			case DialogInterface.BUTTON_POSITIVE: // Yes
			case DialogInterface.BUTTON_NEUTRAL: // No
				WindowManager mWinMgr = (WindowManager) getBaseContext()
						.getSystemService(Context.WINDOW_SERVICE);
				int displayWidth = mWinMgr.getDefaultDisplay().getWidth();
				int displayHeight = mWinMgr.getDefaultDisplay().getHeight();

				Bitmap newwallpaper = Bitmap.createBitmap(displayWidth,
						displayHeight, Config.ARGB_8888);
				Canvas myCanvas = new Canvas(newwallpaper);
				Gallery g = (Gallery) findViewById(R.id.gallery);
				// Draw the image to make sure the aspect ratio match
				((ImageView) g.getSelectedView()).getDrawable().draw(myCanvas);
				try {
					setWallpaper(newwallpaper);
				} catch (IOException e) {
					e.printStackTrace();
				}
				// Save file
				if (DialogInterface.BUTTON_POSITIVE == which) {
					Date date = new Date();
					java.text.DateFormat dateFormat = new java.text.SimpleDateFormat(
							"yyyyMMddhhmmss");
					String dateTimeString = dateFormat.format(date);
					try {
						FileOutputStream fos = new FileOutputStream(new File("/sdcard/" + dateTimeString + ".jpg"));

						newwallpaper.compress(CompressFormat.JPEG, 75, fos);

						fos.flush();
						fos.close();
					} catch (Exception e) {
						Log.e("MyLog", e.toString());
					}
				}
			default: // Cancel
				break;
			}
		}
	};

The important part is inside the try-catch block: setWallpaper(). I also added some image resizing (to make the wallpaper fit the screen) and save to device routine. I’m specifying “/sdcard/” in the FileOutputStream constructor to write to external storage. If you don’t specify this Android will write to your application’s private storage on device memory. Device memory is often much smaller than its external counterpart so it’s best to reserve it for sensitive data you want nobody else to read only.

2.3 Splash screen

Finally, to show tribute to the nice guidance given by the instructor, I have to add a splash screen with MultiUni logo eh? So I added the splash screen activity and change the startup activity to it

public class SplashScreenActivity extends Activity {
	public static final int HANDLER_MSG_WAIT = 1;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash_screen);
        
        mHandler.sendEmptyMessageDelayed(HANDLER_MSG_WAIT, 2000);
    }
    
	Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			Intent intent = new Intent(getApplicationContext(), 
					WallpaperTool.class);
			startActivity(intent);
			finish();
		}
    	
    };
    
}

See the Intent part? it’s used to call another activity. And that’s it!

You deserve something after all that reading, right? 😛 You can grab the source and compiled binary here (for Android 1.6)

Location service emulation on popular platforms

This post in a nutshell: How to run GPS emulation with several mobile platform and a short evaluation of each.

Windows Mobile

On Windows Mobile 5, you get a “GPS” settings applet but there is no GPS emulation tool. The attached documentation (GPS sample) state that you’ll need a real GPS device for the sample to work (and remember to configure it for develapment!); then I downleaded a new version hoping for better support. The first thing I noticed touching the WM6 SDK is the vast amount of tools added: Cellular network emulator, package tools, test framework, and of course among them: a GPS emulator. Looks like Microsoft has finally started to fear Sun.

The GPS emulator is in WM6 SDK folderGPS. Access the CAB file from your device to install it. Additionally, the settings.exe can only be run inside the device and is the same things as the GPS applet. The documentation is still vague, but the tool works.

Here’s the interesting bit: The WM6 FakeGPS work perfectly well on WM5, so you don’t need the new (and huge) SDK to work on location services, just copy the FakeGPS from someone who installed (it’s around 1MB)

020509-1131-locationser1.jpg

The data file structure is pretty clueless, but I may eventually figure that out after some more searching :/

$GPGLL,36000.0000,N,72000.0000,E,000023.998,V*1A
$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$GPRMC,000023.998,V,36000.0000,N,72000.0000,E,0.000000,,101102,,*30
$GPGGA,000024.998,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78
$GPGLL,36000.0000,N,72000.0000,E,000024.998,V*1D

What left to be wondered is, why GPS is taken out of Smartphone and available only for PocketPC? While it’s true that a phone ‘s functionalities are not as easily extended with cards and stuff like a PDA but some of them can locate themselves; or Microsoft thinks 3G should not include location services? Oh well…

Symbian

Given the previous experiences with Symbian, I expected this platform to be the hardest to configure. Looks like I worried too much :). You can select the emulated location service from the phone’s settings. Just go to settings / general / positioning and select simulation, choose settings on this mode to choose emulation data.

Symbian’s emulator can read 2 types of data: the one Windows Mobile used above (nmea.nme is included with the demo) and .sps files. Sps files seem to define non-deterministic movement, like this:

Horizontal accuracy=10;
Vertical accuracy=16;
TimeToFix min=2;
TimeToFix max=7;
Powerup time=5;
Longitude=23.9385;
Latitude=61.5285;
Speed=0;
Course=113.9;
Deterministic=0;

Getting the sample application running is pretty easy too. They even have 4 more examples for this topic and each comes with detailed information on how the classes work.

020509-1131-locationser2.jpg

J2ME

The most straightforward platform! The Location service example is there (called CityGuide), Location and landmark service is built-in with the emulator. To simulate movement, from the emulator choose MIDlet/External events, toward the bottom you’ll see the “Location” group, click Browse to select the path file (City guide comes ready with a path file, citywalk.xml), press play and you are on the move!

The data file is different from both of the above platforms, which belongs to some kind of standard, which is good but to me J2ME’s xml is the best! It’s the cleanest and most human-readable data. Ph34r the power of XML!

<waypoint time="6500" latitude="14.394759972655674" longitude="50.10266737954043" altitude="310" />
<waypoint time="1500" latitude="14.395190022566581" longitude="50.102641304996304" altitude="310" />
<waypoint time="1500" latitude="14.395487422916618" longitude="50.10265163602227" altitude="310" />
<waypoint time="1500" latitude="14.395935213738783" longitude="50.10265925148049" altitude="310" />

020509-1131-locationser3.jpg

I think the landmark tool is build for some purpose, but clearly the sample work well without any tweaking by this tool.

Scary Symbian

I’m not really in the mood to revise writing communication scripts… So I will just blog about Symbian to conclude the assignment I submitted yesterday.

Symbian started as a collaborative Effort between Nokia, Sony Erricson, Samsung and several other mobile phone manufacturers to create an operating system that work for their devices. It’s certainly not the first OS, Palm OS existed long before that. The fact that Symbian collaborated development started in 1998 and got wide attention around 2000 may make you expect a modern operating system with good design while maintaining compatibility.

It’s simply scary for me.

Looking at the sheer amount of features and headers would make you confused, the documentation seems to be machine – generated with very very very few example what each function do. It’s a good thing that a single operating system support all functionality that normally only available on separate devices: media player, digital camera, gaming device… But that is a burden for the developers :(. They will have to get familiar with a multitude of data structures… You think int is just int? No, for Symbian there are 8 bit int, 16 bit int and 32 bit int, and the developer will have to decide what to write both when they design (write the header) and when they code (using the function). Failing to match the two declaration can be fatal and that lead to debug…

To debug you’ll have to install Nokia’s tool: Carbide; which in turn will require you to install

  • Perl
  • Java
  • GNU C++
  • MingW in case you use Windows
  • Phone SDK for simulation; and they install a complete set of files for each SDK

Three languages just to program in one language for one operating system! Even so, if they worked smoothly then there weren’t this post: the SDK installation has a screen in which you can choose where to install, even though you can click the button and change it; and the documentation didn’t recommend otherwise, don’t change it. It will mess up with itself! Installing the SDK in a drive different from the IDE, or different from your workspace drive would results in dumb error messages like “file not found” which unless you are familiar with *nix system, you’ll just went mad! (And even if you have the skill to fix it, are you ready to fix tens of thousands of lines of Perl code just to write a C++ hello world!?)

Expecting the resource editor? It depends on whether you've been nice or naughty…

Expecting the resource editor? It depends on whether you've been nice or naughty…

If you have installed stuff on Windows Mobile before, and ever think to yourself “why must I bring my phone to phone shops, I can do this, piece of cake!”, try using Symbian! Each program throws resource in multiple directories, together with system applications. While this is a good thing on some aspects, a developer just can’t find where his resource file is in the big mess called “sys”. If you think Windows’s window directory on windows mobile is messy because it’s full of dll and executables, have a look at Symbian’s system directory. You’ll see types of files have never seen. Open your eyes and embrace r01, l01, mbm… And because the OS is that complex, OS’s native file structures is complex, to do something as simple as replacing a bitmap, the developer will have to wait for the tools to rebuild it, and then deploy it to the phone, which is not a fast process at all…

And possibly for the same reason why you must rely on shops when your phone has problem, the documentation doesn’t have any mention for any error and how to fix it… Sometimes if you are in luck you may found it in some corner of the Internet. For example a common problem for the 3rd SDK FP1 emulator is it display a kernel failure every time it start. If you google the error, you’ll see several discussion on forum nokia (and several copy of those discussion), most of which will tell you “leave it there, it doesn’t hurt”. It’s not until one beautiful day searching for another kernel problem that I found this KB article: NCNList KERN-EXEC 3 panic when starting the S60 3rd Edition, FP1 emulator. There you go, download the file, install it, and if your phone is happy, it won’t spit a list panic =))

Small community size, clueless forum posts is what you are going to face searching for help with Symbian. I wonder how could they able write so many stuff for their phone? Magic happens among Nokia-employed developers? =))

Some part in their documentation, they mention about how Symbian is so different from normal C, it was designed before the current C++ standards were born. Oh really? How come you can design a new interface for acceleration sensor and can’t even wrap the compiler to use the approrate kind of number and character instead of forcing the developers write clueless stuff like Tint, Tbuf, Tdes, TPtr!? C++ is complex enough already! Keep in mind that you inherited that together with the language next time! Or is it just too hard to let the compiler do exception handling the C++ way instead of some “simple leaves” which make the developer throws away most of their knowledge about constructors to do the so-called “2 phase contruction” like

CBanCo::CBanCo()
{
}
CBanCo::CBanCo(TRect aRect)
{
	iRect=aRect;
	iSize=15;
	iNum=0;
	TRgb color(102,255,255);
	iColor=color;
    iWidth = aRect.Width();
	iHeight = aRect.Height();
	iSwitch = EFalse;
}
void CBanCo::ConstructL()
{
	CSettings* settings = CSettings::NewL();

	iSize = settings->iBoardSize;
	iRow = iHeight/iSize;
	iCol = iWidth/iSize;
	iFlag = false;
	iColCur = iRowCur = 0;
	iArray = NULL; // The following line may fail
	iArray = new (ELeave) CArrayFixFlat(iRow*iCol);
		for(TInt i=0 ; i < iRow ; i++)
			for(TInt j=0 ; j < iCol ; j++)
				iArray->AppendL(-1);
	if (settings->iPlayerSymbol == 0)
		iSwitch = EFalse;
	else
		iSwitch = ETrue;
	iImageX = AknIconUtils::CreateIconL(BitmapStore, (iSwitch == EFalse? 2 : 3));
	iImageO = AknIconUtils::CreateIconL(BitmapStore, (iSwitch == EFalse? 3 : 2));

	delete settings;
}
CBanCo::~CBanCo()
{
	if (iArray != NULL)
		delete iArray;
	if (iImageX != NULL)
		delete iImageX;
	if (iImageO != NULL)
		delete iImageO;
	iArray = NULL;
	iImageX = NULL;
	iImageO = NULL;
}
CBanCo* CBanCo::NewL(TRect aRect)
{
	CBanCo* myObj = CBanCo::NewLC(aRect);
	CleanupStack::Pop(myObj);
	return myObj;
}
CBanCo* CBanCo::NewLC(TRect aRect)
{
	CBanCo* myObj = new (ELeave) CBanCo(aRect);
	CleanupStack::PushL(myObj);
	myObj->ConstructL();
	return myObj;
}

While it could be

CBanCo::CBanCo()
{
	;
}
CBanCo::CBanCo(TRect aRect)
{
	iRect=aRect;
	iSize=15;
	iNum=0;
	TRgb color(102,255,255);
	iColor=color;
    iWidth = aRect.Width();
	iHeight = aRect.Height();
	iSwitch = EFalse;
	CSettings* settings = new CSettings();
	iSize = settings->iBoardSize;
	iRow = iHeight/iSize;
	iCol = iWidth/iSize;
	iFlag = false;
	iColCur = iRowCur = 0;
	iArray = NULL; // The following line may fail
	iArray = new (ELeave) CArrayFixFlat(iRow*iCol);
		for(TInt i = 0; i < iRow ; i++)
			for(TInt j=0 ; j < iCol ; j++)
				iArray->AppendL(-1);
	if (settings->iPlayerSymbol == 0)
		iSwitch = EFalse;
	else
		iSwitch = ETrue;
	iImageX = AknIconUtils::CreateIconL(BitmapStore, (iSwitch == EFalse? 2 : 3));
	iImageO = AknIconUtils::CreateIconL(BitmapStore, (iSwitch == EFalse? 3 : 2));
	delete settings;
}
CBanCo::~CBanCo()
{
	if (iArray != NULL)
		delete iArray;
	if (iImageX != NULL)
		delete iImageX;
	if (iImageO != NULL)
		delete iImageO;
	iArray = NULL;
	iImageX = NULL;
	iImageO = NULL;
}

See it? my code hilighter can’t parse Symbian C++ as C++ :))… I stray too far from the debug part, didn’t I? Yes, the debugger does not allow code view, and because it stops immediately when some error happens, you can’t see the values you are tracking at that time. Proved you are clever enough to have the debug work while winscw’s configuration just won’t start.

Guess that when the phone is sold to the rich, its developers should also be rich and have a lot of spare time to think like the rich then. At least the OS have a nice interface after all

Symbian gomoku, thanks to my instructor

Symbian gomoku, thanks to my instructor

Strangely, I can’t help noticing Nokia still has the largest market share in the smartphone market according to canalysis (51% in 2007). I just can’t find a nice chart to match smartphone sales to dumb phone’s so I can’t just conclude that most of the rich people uses an inextricably complex operating system 😛

Nevertheless, iPhone is steadily gaining its part and the first dream phone (as what Google calls it) appeared a couple of months ago also with quite a lot of function. Both of which could be interesting factors to facilitate Symbian in the future.