Setting up Android development environment in Windows and Linux

The number of apps in the Android market has been growing at a breakneck speed and soon looks to surpass 100,000, giving the iPhone app store a run for its money. The developer community has been showing some serious interest in developing apps for Android as well as contributing to the OS codebase. The lower entry fees (25$) as compared to the iPhone ($99), combined with the more liberal acceptance criteria has done much to fuel interest.

There are two kinds of contributions that interested developers can make to the Android platform. First is testing out and submitting patches to the Android codebase and the other is to write applications targeting the platform. The applications are to be written in Java which simplifies the development process by quite a bit. I wrote this post to show how to set up the Android development environment to write apps.

Before starting development, there are a few points every new mobile app developer should keep in mind. Though not an exhaustive list, it serves as a reminder of few crucial points.

A more comprehensive discussion can be found here.

  • The Java code that you write isnt compiled by the usual JVM but a lighter implementation called Dalvik. So a lot of compiler/runtime optimizations are unavailable to us yet. Just in Time Compilation has just been added in Froyo. Other optimizations like Method inlining, caching are not added so use direct fields where possible rather than properties.
  • Responsiveness is of paramount importance in a mobile OS. On a PC, people might not notice lags of a second or so, but on a handheld device, even the smallest of lags is instantly noticeable and decreases the user experience
  • Don’t take device display for granted. Android has been used on devices with varying display sizes – from phones to netbooks to tablet pcs. So while coding the layout, keep the appplication as end device agnostic as possible.

To get started, we need the following components.

  • Eclipse IDE (both Windows and Linux)
  • ADT plugin for Eclipse
  • Google SDK
  • Android platform components.

First the Eclipse IDE. This by the way, is the only step that would differ between Windows and Linux. All others are pretty much the same.

On Windows, the IDE can be downloaded from the site – http://www.eclipse.org/downloads/ and run the setup to install. Linux’s package manager makes the install a simple one step process. In the command line type

sudo apt-get install eclipse

Next, download the Google Android SDK from this page as per your platform. The MD5 checksums for the archive are given, so you can verify the integrity of the file after download. Expand the archive to the disk. Now we need to install the ADT plugin for Eclipse. To do that go to Help -> Install New Software. Here the site of the ADT plugin needs to be added – https://dl-ssl.google.com/android/eclipse/. Once that is done click Add, and choose both  Android DDMS and Development tools and click Finish to install them

Now open Eclipse and choose Window -> Preferences -> Android. In the Options page, give the path of the folder where you stored the SDK.

Once that is done, we need to download the SDK components. These components differ for each API version. The higher the version goes, the more features you will get. But the number of devices your application will support would also decrease. So its always better to target the most stable current release which would be on a majority of devices. Go to Window ->Android SDK and AVD manager. In the Virtual Devices tab click Add and create a new Android Virtual Device. This is the emulator that we can use to test our applications on. Enter the required details and remember to set the memory card size above 10 MB. Once you Create the AVD, it will show up in the Virtual devices tab.

Then, select the Available packages tab in the same window and click on the plus sign next to the web address. This will give us the available packages which can be installed. Choose any one of your choice and click Install Selected.

Once the SDK is installed you will be able to create Android applicatons by Going to File -> New -> Project -> Android Project. In my next post I will explain how to write a simple Android application.

Use AndroidVNC on your phone to control Ubuntu running on a Virtual Machine

AndroidVNC is an Android app that can be used to connnect and control a remote machine which runs a VNC server. There are many VNC servers available like RealVNC, TightVNC, X11VNC server etc. The VNC server listens to a port (typically 5900) which the VNC client, can connect to and view/control the machine remotely.

Running it on a machine is quite straightforward. All you need to do is to start the TightVNC service and connect it from the phone using the app that can be downloaded from the market. It works great and can be used to control your PC from anywhere as long as its connected to the net.

But when you want to connect to a machine running on a VM, things can get a bit tricky. Mainly because of the way VirtualBox works. The default networking mode between a Host OS and the guest OS is NAT (Network Address Translation), which makes the VirtualBox as an intermediary between the Host and the guest and maps traffic to and fro. Though this mode requires virtually no configuration, it also makes the guest OS inaccessible from the outside world. Since any VNC viewer requires connectivity to the VNC server running on a machine, this limitation was effectively a dealbreaker.

To avoid this, the packets which reach the host must be sent to the guest through some mechanism. VirtualBox provides such a mechanism to do it and the protocol is called SSH (Secure Shell) which allows two networked devices to exchange data with each other. What happens is we open a port on the host side and forward any data received to a specified port on the guest through TCP. However, the GUI interface doesn’t give this option, its in a command line tool called VBoxManage. Before running this command, get the local IP address from Ubuntu using the ifconfig command. The IP was 10.0.2.15

Now we need to tell VirtualBox to forward all data received on any specified host port to port 5901 on Ubuntu.
I used the port 2222. The command for this is given below. Keep in mind that the VM needs to be powered off to use this command. Here you need to substitute your VM name with VM_NAME_here parameter. The guestssh is just a name assigned to it and doesnt really matter. Next comes the protocol – TCP, followed by the port on the host 2222. The two values after it signify the local IP for the guest OS and and port on the guestOS which will recieve the data.

VBoxManage modifyvm "VM_name_here" --natpf1 "guestssh,tcp,,2222,10.0.2.15,5901"

Now that forwarding is configured, power on the VM again and install any VNC server on Ubuntu. I used X11VNC for this exercise.

sudo apt-get install x11vnc vnc-java

After X11VNC is installed, start it by going to Applications -> Internet -> X11 VNC server. It will display a dialog asking for the options. Make sure the port is 5901 and click on OK.

After clicking on OK, in the next screen. Make sure the Accept Connections tab is checked and also give a password and click on Ok. The X11VNC should be visible on the top left of the screen (If you are using GNOME)

Now that VNC is listening to port 5901 on the server, you can test it by running a VNC viewer on the localhost and specifying the port 2222 and seeing if the connection is made. The host would be 127.0.0.1::2222. This connection should be forwarded to the Ubuntu’s 5901 and the connection should succeed. If not see the logfile of the X11VNC to see if the connection was rejected due to some reason.

If your all set, run the AndroidVNC application on your phone. Also a very important point – “If you are accessing the net through a slow connection such as GPRS, make sure the resolution on Ubuntu is set to the miminum to prevent timeouts.” Get the network IP of your host through ipconfig or a site such as whatsmyip.com and enter the required settings on your phone.

Nickname: Any nickname you want
Password : What you specificied on X11VNC
Address: The public IP of your computer you got from ipconfig.
Port: 2222

And hit connect. It might take upto a minute to draw the first frame. Once thats done, you will be able to completely control the computer from your phone.

You can also send text and other key commands to the VM from your phone using the app options. Just How cool is that??

Android for wordpress

Android for wordpress is a free android app that lets you manage your wordpress blog from your phone. Though quite basic, it certainly seems to be the best blogging solution on the android right now. Making this post using the app. Wonder if we will get the plugins for this app in the near future.

Troubleshooting the infamous 0x7B INACCESSIBLE_BOOT_DEVICE Blue screen in Vista

Blue screen of death (BSOD) errors may drive people crazy, but they really are useful in pinpointing the root cause of the problem preventing the computer from starting up. Beneath that obscurity, there is enough hidden information to help fix nagging errors. However one dreaded BSOD which still is a tricky customer is the 7B or INACCESSIBLE_BOOT_DEVICE error. Its causes can be many and each has its own solution without a guarantee of success.

So yesterday, when my Vista laptop was stuck in a restart loop with this error, I knew it was going to be a long night. After trying a million different things, I finally gave up at 5 AM, too tired to carry on. Today, after even more endless rounds of restarts and head banging, it finally got resolved and I saw the magical Vista login screen. :) I listed down a few of the steps I followed – might be useful for others haunted by this deathly error.

  • Pinpoint the cause: Doctors don’t charge you for prescribing the right medicine, they charge you for getting the diagnosis right. Once that part is solved, the cure just falls into place. Its the same case with BSODs. Google/Bing can help you out here in finding the documentation for each error which can help you find out what is exactly wrong. However some, like the 7B are different. It can be caused by hardware failures, SATA/IDE compatibility issues, wrong RAID settings, boot sector issues among others. The trick is to isolate each of them one by one.
  • Check what changed: Errors usually occur due to something that has changed recently. Remembering any settings/configurations/hardware changes you recently did can go a long way in helping us pinpoint the cause. In my case I had made two changes, one was turning off DEP to speed up large file copying in Vista and forgetting to unplug my external hard drive while rebooting. Both changes effect the Vista BCD (Boot configuration data).
  • Check the hardware: If there is something a few months in tech support have taught me, its the golden rule that no amount of software troubleshooting can fix a hardware error. Always run your diagnostics first. Dell comes with a range of built in utilities to do just that. The Preliminary PSA tests can be started by pressing F12 while windows boots and choosing Diagnostics. It first runs some basic hardware and memory tests and then gives more options. For 7B, the hard drive is a likely culprit so run all the tests on it to make sure. Also run chkdsk  /f which scans for any bad sectors and marks them to be avoided later. Bad sectors in the boot record can also lead to the error.
  • Check the BIOS: After the hardware, the BIOS is also a major cause of 7B errors. It could be a SATA mode or RAID settings issue. Try changing the settings for SATA operations from AHCI to ATA (could be named differently in your BIOS). If it doesn’t work, change them right back. This article gives a description of the issue and resolution.
  • Give automated repair options a shot: There are two automated recovery options in Vista – one is the startup repair and the other is system restore. Experienced users usually look down on automated options as being reserved for the dummies. True they don’t work most of the time, but its still worth a shot. The next point will elaborate on how to get the automated repair options
  • Use Windows Recovery Environment: WinRE is a set of very useful tools which is bundled in vista. It gives you access to System Restore, Memory diagnostics, PC Restore and command prompt. WinRE can be started from the local computer by pressing F8 during boot and choosing Repair Computer in the menu. It can also be started from the Vista DVD , by booting into it and clicking Repair on the installation screen. The command prompt can be used to launch many boot utilities along with regedit.
  • BCDEdit and BootRec: Both of these are utulities which can be used to fix the boot record of Vista which can get corrupted due to a number of reasons, one of them being installation of another OS in the system. Bootrec has four options – fixboot, fixMBR, RebuildBCD and ScanOS. Their functions taken from this support article are given for easy reference. In my case the ScanOS wasnt able to identify any OS installations on the drives. So basically, the Boot record was toast and had to be rebuilt manually. Given the alternative of a format and fresh install, this option sounded like lesser work.
/FixMbr
The /FixMbr option writes a Windows 7 or Windows Vista-compatible MBR to the system partition. This option does not overwrite the existing partition table. Use this option when you must resolve MBR corruption issues, or when you have to remove non-standard code from the MBR.
 
/FixBoot
The /FixBoot option writes a new boot sector to the system partition by using a boot sector that is compatible with Windows Vista or Windows 7. Use this option if one of the following conditions is true:
The boot sector has been replaced with a non-standard Windows Vista or Windows 7 boot sector.
The boot sector is damaged.
An earlier Windows operating system has been installed after Windows Vista or Windows 7 was installed. In this scenario, the computer starts by using Windows NT Loader (NTLDR) instead of Windows Boot Manager (Bootmgr.exe).
 
/ScanOs
The /ScanOs option scans all disks for installations that are compatible with Windows Vista or Windows 7. Additionally, this option displays the entries that are currently not in the BCD store. Use this option when there are Windows Vista or Windows 7 installations that the Boot Manager menu does not list.
 
/RebuildBcd
The /RebuildBcd option scans all disks for installations that are compatible with Windows Vista or Windows 7. Additionally, this option lets you select the installations that you want to add to the BCD store. Use this option when you must completely rebuild the BCD.
  • Rebuilding the BCD: After stumbling on a lot of dead ends to repair the boot sector. I finally found an article which explains how to do so. I used the following commands in the article to manually create a new BCD entry and assign it the path of the Windows directory.  Then the new entry is made default and the old one deleted.
bootrec.exe /fixmbr
x:\boot\bootsect.exe /nt60 all /force
Now we get rid of the old BCD registry, and create a new one instead.
Note: We're assuming that the boot drive is drive C: below. If your computer is configured differently, be sure to use the appropriate drive letter here instead.
 
del C:\boot\bcd
bcdedit /createstore c:\boot\bcd.temp
bcdedit.exe /store c:\boot\bcd.temp /create {bootmgr} /d "Windows Boot Manager"
bcdedit.exe /import c:\boot\bcd.temp
bcdedit.exe /set {bootmgr} device partition=C:
bcdedit.exe /timeout 10
del c:\boot\bcd.temp
Now we have a clean, working Vista bootloader. But we need to add a Vista entry to it:
 
bcdedit.exe /create /d "Windows Vista" /application osloader
bcdedit.exe should return a message with a GUID for the newly-created entry, something like this:
The entry {c0dfc4fa-cb21-11dc-81bf-005056c00008} was successfully created.
 
You'll need to use the value that bcdedit.exe returned for you below, along with the drive letter for the drive that Windows Vista is installed to:
 
bcdedit.exe /set {c0dfc4fa-cb21-11dc-81bf-005056c00008} device partition=C:
bcdedit.exe /set {c0dfc4fa-cb21-11dc-81bf-005056c00008} osdevice partition=C:
bcdedit.exe /set {c0dfc4fa-cb21-11dc-81bf-005056c00008} path \Windows\system32\winload.exe
bcdedit.exe /set {c0dfc4fa-cb21-11dc-81bf-005056c00008} systemroot \Windows
 
bcdedit.exe /displayorder {c0dfc4fa-cb21-11dc-81bf-005056c00008}
bcdedit.exe /default {c0dfc4fa-cb21-11dc-81bf-005056c00008}

This finally fixed my problem, and hopefully yours too!! Even if it didn’t, I hope there was enough information in the post to point you in the right direction.

Flot - JQuery charting plugin used to plot Prepaid/Postpaid usage trends

A few weeks back, Ibrahim told me about a cool JQuery plugin – Flot which makes charting really easy. So I played around and worked out an example. It plots your total cost versus minutes for both postpaid and prepaid mobile connections. Just enter the plan details for both prepaid and postpaid and you get the graph, which could be used to compare which plan suits your usage range. Postpaid plans usually have a monthly recurring cost but also give away free minutes. So it makes sense to go for it only if your monthly usage exceeds certain number of minutes. This graph will show the minimum usage beyond which its profitable to go for a plan.

You can check out the demo page here. A Screenshot is below

Flot can be downloaded here. You can also check out the API documentation and the examples. The code for the example is given below and you can also download it from the site.

Javascript:-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/* ************************************************
* Developer: Ganesh Ranganathan
* Date: 07-June-2010
* Description: This is an example for Flot-  a Jquery plugin
* ***********************************************/
 
//A class which encapsulates the cost for both prepaid and postpaid
function Cost(monthly, free, local, std, sms) {
    this.monthly = monthly;
    this.free = free;
    this.local = local;
    this.std = std;
    this.sms = sms;
 
    //This function calculates  the cost, its supplied with the number of prepaid and post paid
    this.Calculate = function(minutes, stdProp) {
        //If the number of minutes is less than free minutes, just return the monthly recurring and SMS cost
        if (minutes < free)
            return parseInt(monthly) + (parseInt(sms * appVariables["sms"]));
        else
            minutes = minutes - free; // reduce free minutes
        var stdPropMin = minutes * stdProp; // calculate number of STD
        var localPropMin = minutes * (1 - stdProp);
        //return the total cost
        return (parseInt(monthly) + (parseInt(local * localPropMin)) + (parseInt(std * stdPropMin)) + (parseInt(sms * appVariables["sms"])));
    }
}
 
//No Magic numbers anywhere. Any constants/default variable value should be entered here
//and accessed. Customize defaults later using other controls
var appVariables =
{
    minuteRange: 800, //Max minutes per month
    allowedChars: [8, 190], //All allowed character inputs for cost boxes
    serviceTaxPercent: 10.2, //Service tax percentage - not applicable for prepaid
    sms: 50, // Number of SMS sent per month -- **customize later**
    stdProp: 0.5 //Proportion of STD to local -- **customize later**
}
 
//Chart options. Refer API.txt for complete list of
//available options
var chartOptions = {
    yaxis: { min: 0 },
    xaxis: { tickDecimals: 0 },
    series: {
        lines: { show: true }
    }
};
 
//This JSON variable will hold the data. Empty now - data will be calculated dynamically
//based on the cost
var dataset =
{
    "prepaid": {
        label: "prepaid",
        data: [[0,0]]
    },
    "postpaid": {
        label: "postpaid",
        data: [[0,0]]
    }
};
 
//This is the array which holds the data. We will pass
//it to FLOT.
var data = [dataset["prepaid"], dataset["postpaid"]];
 
//This is init function run after DOM loads
$(document).ready(function() {
 
    //Push all the allowed charcters in the array.
    for (var i = 48; i < 58; i++)
        appVariables["allowedChars"].push(i);
 
    //Set all cost boxes to 0
    $('.cost').each(function() {
        $(this).val(0);
    });
 
    //Hooking up event handlers - The keyup event redraws the chart, while keydown event validates data
    //If keydown validates false, it cancels the input
    $('.cost').keydown(checkInput);
    $('.cost').keyup(redrawChart);
 
    //Plot the chart. We pass the placeholder of the chart, the data array
    //and the options array
    var plot = $.plot($("#chart"), data, chartOptions);
 
});
 
//Function to check input. If the entered key isnt in the allowed character array, the input is cancelled.
//Its enough to validate here since keyup will be fired after here
var checkInput = function(event) {
    var found = false;
    for (var i = 0; i < appVariables["allowedChars"].length; i++) {
        if (event.keyCode == appVariables["allowedChars"][i])
            found = true;
    }
    if (!found)
        return false;
};
 
//Function to redraw the chart. IT will be fired once the costboxes's value is changed
var redrawChart = function(event) {
    //First all arrays need to be set to null. This
    //is important since we are pushing the data in
    //the array and not index setting it
    dataset["postpaid"]["data"] = [[]];
    dataset["prepaid"]["data"] = [[]];
    //Call the functions to populate the arrays.
    calculatePostPaid(appVariables["minuteRange"]);
    calculatePrePaid(appVariables["minuteRange"]);
 
    //Plot the chart. We pass the placeholder of the chart, the data array
    //and the options array
    var plot = $.plot($("#chart"), data, chartOptions);
};
 
var calculatePostPaid = function(minuteRange) {
    //Get monthly recurring cost. We need to add the service tax to it
var monthly = parseInt($('#postMonthly').val()) * (1 + appVariables["serviceTaxPercent"] / 100);
    //Get the free minutes, local cost, std cost and sms cost from the text boxes
    var free = $('#postFree').val();
    var local = $('#postLocal').val();
    var std = $('#postStd').val();
    var sms = $('#postSMS').val();
    //Create the cost object and pass all values to its
    //constructor
    var postCost = new Cost(monthly, free, local, std, sms);
    //Push the data into the array. Calculate for each minute the cost using the
    //Cost class's calculate method.
    for (var i = 0; i < minuteRange; i++)
        dataset["postpaid"]["data"].push(new Array(i, postCost.Calculate(i, appVariables["stdProp"])));
};
 
var calculatePrePaid = function(minuteRange) {
//Get the free minutes, local cost, std cost and sms cost from the text boxes
    var monthly = $('#preMonthly').val();
    var free = $('#preFree').val();
    var local = $('#preLocal').val();
    var std = $('#preStd').val();
    var sms = $('#preSMS').val();
    //Create the cost object and pass all values to its
    //constructor
    var preCost = new Cost(monthly, free, local, std, sms);
    //Push the data into the array. Calculate for each minute the cost using the
    //Cost class's calculate method.
    for (var i = 0; i < minuteRange; i++)
        dataset["prepaid"]["data"].push(new Array(i, preCost.Calculate(i,appVariables["stdProp"])));
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<html>
<head>
<title>Flot </title>
<link rel="Stylesheet" type="text/css" href="Styles/layout.css" />
<script language="javascript" type="text/javascript" src="js/jquery.js"></script>
<script language="javascript" type="text/javascript" src="js/jquery-ui-1.7.1.custom.min.js"></script>
<script language="javascript" type="text/javascript" src="js/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="js/myscript.js"></script>
</head>
<body>
<div id="chart">
</div>
<div id="optionsHolder" class="divOptions">
<table id="tblOptions">
<caption>Enter the cost</caption>
<tr>
<th scope="col">Charges For</th>
<th scope="col">Prepaid</th>
<th scope="col">PostPaid</th>
</tr>
<tr id="rental">
    <td>Monthly Recurring Cost</td>
    <td><input type="text" id="preMonthly" class="cost" /></td>
    <td><input type="text" id="postMonthly" class="cost"/></td>
</tr>
<tr id="freeMinutes">
    <td>Free Minutes</td>
    <td><input type="text" id="preFree" class="cost" /></td>
    <td><input type="text" id="postFree" class="cost"/></td>
</tr>
<tr id="localCost">
    <td>Local Call: </td>
    <td><input type="text" id="preLocal" class="cost" /></td>
    <td><input type="text" id="postLocal" class="cost"/></td>
</tr>
<tr id="stdCost">
    <td>STD Call: </td>
    <td><input type="text" id="preStd" class="cost" /></td>
    <td><input type="text" id="postStd" class="cost"/></td>
</tr>
<tr id="smsCost">
    <td>SMS: </td>
    <td><input type="text" id="preSMS" class="cost" /></td>
    <td><input type="text" id="postSMS" class="cost"/></td>
</tr>
</table>
</div>
</body>
</html>

Program to the interface, not the implementation

I got this invaluable piece of advice while reading the book Code Complete by Steven Mc Connell. Program to the interface, not the implementation.

Coding to the implementation is a mistake which most developers (including me), are guilty of. Now, digging deep into the external classes for educational purposes is a perfectly healthy activity and seeing code written by developers greatly improves your own skills. However, the problem starts when decisions are made based on the internal implementation details of a class. On the surface this might seem a very intelligent thing to do, but it can lead to plenty of unpleasant consequences.

  • For starters, it completely goes against the philosophy of Object Oriented programming that client classes look inside the server object to work out the way they need to make the call. A class should behave like a black box and should only expose to the outer world, what  it wants to. If you need more details, they should come from the documentation and not the source code.
  • It also deprives the application developer of the independence to change/optimize/upgrade his own implementation. If the client class is coded on any assumptions, the application will break when they are voided due to changes. This makes the client-server tightly coupled, an arrangement frowned upon by seasoned architects.
  • There may be scenarios where you absolutely need to code based on the implementation due to incomplete information at your disposal, but it’s always better to call up the developer and ask him to fix both the interface and the documentation. Because every time a change is made, he is obliged to keep those up to date, but by no means will the developer look into your code and advise you on how to modify it to make it work.

Lifting the .NET Hood – Part 2 - Back to basics

When I looked at the first post in this series, I realized had jumped the gun a bit by going straight to generics and didn’t do enough justice to the fundamentals. So in this post, I have made an effort to go back to the basics.

The CLR (Common Language Runtime) is the heart of .NET. It’s the virtual execution system responsible for converting the platform neutral CIL (Common Intermediate Language) into platform specific and optimized code. The CLR provides services like memory management, garbage collection, exception handling and type verification. Thus it allows language designers to concentrate solely on outputting good CIL and provides a uniform API to allow language interoperability.

The only truth in .NET is the assembly code which is the final product. All the rest are virtual constraints enforced by the execution system in a very robust manner. For e.g. A memory address declared as int cannot take a string value, not because the memory is not able to take the value, but rather the CLR makes sure the values conform to the types declared – a feature called type verification. Usually this happens at the compilation level, but still rechecked at runtime.

Microsoft released the code of the CLI (Common Language Infrastructure) under the name SSCLI (Shared Source CLI). It can be downloaded here. Joel Pobar and others wrote a great book about it. Unfortunately the 2.0 version is still a draft.

Type safety is the most important aspect of .NET programming and a lot of thought went into it. A type can be thought of as a contract which the objects need to conform to. For e.g. in the following code, the Person class is a type – which is supposed to have five public variables and one method. Any object that claims itself to be a person type must necessarily fulfill this contract – or the CLR will reject it during runtime. While working with the more mature compilers like C# and VC++, these checks are already done while converting the code to CIL.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Person
{
    public string _name;
    public int _ssn;
    public char _middleName;
    public decimal _phoneNumber;
    public char _bloodGroup;
 
    public Person(string name, int ssn, char middleName, decimal phoneNumber, char bloodGroup)
    {
        this._name = name;
        this._ssn = ssn;
        this._middleName = middleName;
        this._phoneNumber = phoneNumber;
        this._bloodGroup = bloodGroup;
    }
 
    public string GetSomeDetails()
    {
        return String.Empty;
    }
}
 
static void Main(string[] args)
{
    Person _p = new Person("John Doe", 4454353, 'B', 324242432, 'O');
    _p.GetSomeDetails();
}

The code for object class can be found at sscli20\clr\src\vm\object.h in the SSCLI code and the Type class at \sscli\clr\src\vm\typehandle.h. The Type class which is extensively used in Reflection for reading the type metadata is a wrapper for this TypeHandle class. Lets look at the underlying code for some familiar methods of the TypeHandle, some of which you see in Type Class. So every object that declares itself of this type, indirectly points to the data structure to define itself.

1
2
3
4
5
6
7
8
    BOOL IsEnum() const;
    BOOL IsFnPtrType() const;
    inline MethodTable* AsMethodTable() const;
    inline TypeDesc* AsTypeDesc() const;
    BOOL IsValueType() const;
    BOOL IsInterface() const;
    BOOL IsAbstract() const;
    WORD GetNumVirtuals() const;

The MethodTable that you see is the datastructure which contains the frequently used fields needed to call the methods. Along with another structure called EEClass, it defines the type identity of an object in .NET. The difference is that the MethodTable contains data that is frequently accessed by the runtime while the EEClass is a larger store of type metadata. This metadata helps querying type information and dynamically invoking methods using the Reflection API. Using the SOS dll’s DumpHeap command, the address of all the types can be gotten and used to see the EEClass and MethodTables. Lets examine the Person type in the above example.

.load SOS
extension C:\Windows\Microsoft.NET\Framework\v2.0.50727\SOS.dll loaded
 
!DumpHeap -type Person
PDB symbol for mscorwks.dll not loaded
 Address       MT     Size
020a34d4 001530f0       36
total 1 objects
Statistics:
      MT    Count    TotalSize Class Name
001530f0        1           36 DebugApp.Person
Total 1 objects
 
//Getting the address and using the DumpObj command
 
!DumpObj 020a34d4
Name: DebugApp.Person
MethodTable: 001530f0
EEClass: 001513d0
Size: 36(0x24) bytes
 (D:\Ganesh Ranganathan\Documents\Visual Studio 2005\Projects\DebugApp\DebugApp\bin\Debug\DebugApp.exe)
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
70d00b68  4000001        4        System.String  0 instance 020a34b0 _name
70d02db4  4000002        8         System.Int32  1 instance  4454353 _ssn
70d01848  4000003        c          System.Char  1 instance       42 _middleName
70cd7f00  4000004       10       System.Decimal  1 instance 020a34e4 _phoneNumber
70d01848  4000005        e          System.Char  1 instance       4f _bloodGroup

Lets dissect this output. First the DumpObj command lists both the MethodTable and the EEClass address and the proceeds to list the fields . See how the value column lists the direct value for the int and char fields while the address is listed for the reference type string. However the bigger decimal type, which actually is a struct and hence a value type, displays the reference. Though SOS displays the reference, we can observe that the address is actually an offset from the object header, which means that it is still stored by value and not the reference. Looking at the memory window for the string and decimal fields’s address gives their original values.


Viewing the object in the memory window shows a pattern of how the runtime stores the values in memory. The object starts with a reference to the MethodTable, then the fields are lined up. It can be observed that there is a difference in how the runtime stores the values of the fields and how we defined them. For e.g. The two character fields are pushed together in spite of not being declared sequentially. This is done to save memory and the runtime is able to manage this situation because all it stores is the memory offset of the fields from the header. To avoid this behavior, types can be decorated with the [StructLayout(LayoutKind.Sequential)] attribute, often used while marshalling data out of managed code, because unmanaged code cant deal with such vagaries. You should also pin your objects, especially references while passing them to unmanaged code, because the runtime keeps moving the memory blocks around.

Now lets look at the MethodTable through SOS. As you can see, every type also inherits the methods from its parent, in this case System.Object. The MethodTable also contains a pointer to the EEClass. When it is laid out during type creation, the method points to a temporary piece of code called a thunk. The thunk in turn calls the JIT compiler and asks it to compile the method. This lazy compilation works wonders for performance and the memory footprint. Once the method is compiled the JIT updates the method to point to the compiled code instead of the thunk.

!DumpMT -MD 001230f0
EEClass: 001213d0
Module: 00122c5c
Name: DebugApp.Person
mdToken: 02000005  (D:\Ganesh Ranganathan\Documents\Visual Studio 2005\Projects\DebugApp\DebugApp\bin\Debug\DebugApp.exe)
BaseSize: 0x24
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 6
--------------------------------------
MethodDesc Table
   Entry MethodDesc      JIT Name
70c56aa0   70ad4a34   PreJIT System.Object.ToString()
70c56ac0   70ad4a3c   PreJIT System.Object.Equals(System.Object)
70c56b30   70ad4a6c   PreJIT System.Object.GetHashCode()
70cc7550   70ad4a90   PreJIT System.Object.Finalize()
0012c030   001230c4      JIT DebugApp.Person..ctor(System.String, Int32, Char, System.Decimal, Char)
0012c038   001230d4     NONE DebugApp.Person.GetSomeDetails()

You can see the JIT column says none for the GetSomeDetails method and thats because it hasnt been called yet. After its called for the first time, the method is JIT compiled and the MethodDesc shows the code address where the compiled code can be found. Note however, that the MethodDesc is not the usual route for the runtime to execute methods, it is rather done directly. Only when the method is invoked by its name, is the MethodDesc required.

!DumpMT -MD 001230f0
EEClass: 001213d0
Module: 00122c5c
Name: DebugApp.Person
mdToken: 02000005  (D:\Ganesh Ranganathan\Documents\Visual Studio 2005\Projects\DebugApp\DebugApp\bin\Debug\DebugApp.exe)
BaseSize: 0x24
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 6
--------------------------------------
MethodDesc Table
   Entry MethodDesc      JIT Name
70c56aa0   70ad4a34   PreJIT System.Object.ToString()
70c56ac0   70ad4a3c   PreJIT System.Object.Equals(System.Object)
70c56b30   70ad4a6c   PreJIT System.Object.GetHashCode()
70cc7550   70ad4a90   PreJIT System.Object.Finalize()
0012c030   001230c4      JIT DebugApp.Person..ctor(System.String, Int32, Char, System.Decimal, Char)
0012c038   001230d4      JIT DebugApp.Person.GetSomeDetails()
 
!DumpMD 001230d4
Method Name: DebugApp.Person.GetSomeDetails()
Class: 001213d0
MethodTable: 001230f0
mdToken: 06000007
Module: 00122c5c
IsJitted: yes
CodeAddr: 009f01c8

In this post we saw basic functioning of the CLR and how it creates and stores internal data structures to facilitate code execution at the same time abstracting away all the gory details from the developer and allowing him to solely concentrate on his applications. Below the hood everything is simply memory addresses pointing to each other and a bunch of assembly code. To give it such a high degree of structure and definition is by no means an easy task. Hats off to the developers in the .NET and Java teams!! Hope I am able to reach their skill levels one day. :)

How to save your application from getting trashed

You spend a lot of time in creating an application, starting with abstractions and slowly moving to the specifics,  hours of heated debate to painstakingly design each and every intricate detail, working on all possibilities for  extensibility, even going through every line of code other developers write to make sure they stick to the design.  Yes, a lot of effort goes into creating and delivering a production quality application which satisfies all the  stakeholders.

Ideally, thats when a developer should say goodbye to the application vowing never to see the code again. Coz, if  he does, he’d end up mighty disappointed. Future developers would have literally pillaged the application to  systematically eliminate any traces of the original design, the code would be littered with dirty bug fixes and so -called enhancements that don’t “enhance” anything. The customer doesn’t care because the application still works,  the managers don’t care because they meet their revenue targets and the timelines, and the developers never cared  in the first place.

Keeping that in mind, I listed down a few ways which might help save your application from meeting the same fate.

  • Keep it Simple:  The oft repeated rule in software design is “Keep everything as simple as possible, but not  simpler”. If the design is too complex, then in all probability no developer would take the pains to go through it  and understand the whole thing. Many software engineers are guilty of trying to force fit their code to use a certain design pattern. Instead,look for the pattern which best fits your requirement
  • Keep it Modular: Dividing your application into logically seperated projects makes it easier to identify the right  places to make the changes. Proper namespaces help too. For e.g. an assembly with the namespace  ABCApplication.HelperObjects.FileIOOperations leaves no space for doubt about what it does.
  • Keep it Visual: Sure, you might find the 1000 page SMTD an interesting read, but not everyone else will. Remember a  bored developer would be the most likely to introduce a dirty fix in the code. So, to keep things interesting, go  for easy to understand graphics and images. MS Visio is a great tool to model your application, and it supports  automatic code generation as well (Enterprise Architect version). And after creating the model, dont leave it in a  random location that even you would forget in 2 weeks. My advice is to check it in the Source control along with  the code and add it to the Visual Studio Solution.
  • Keep it Commented: Good commenting is the most potent weapon in your arsenal to guide/warn/ prohibit future  developers from making changes they shouldnt be doing. XML comments are a great way to maintain uniform commenting  standards across the application and can also be used to generate comment documentation automatically (using the  /doc switch while compiling) . A good way to convey how you intended the code to be used is to include a sample code block in the xml comments itself. Keep it mind though, that the comments are stripped out by the compiler, so  if you want comments to appear in the intellisense while using the assemblies, then the generated documentation  file must be packaged along with the assembly.

Google Maps API - Getting started

Even the simplest data driven applications today are not only about gathering, understanding and digesting data. Its also important to decide how you display it in such a manner that the user is able to get the gist in the least amount of time. A great way to do that is display data as graphically as possible – with Charts, Graphs and maps. For displaying maps there are quite a few APIs available – Google Maps, Yahoo maps and Bing maps.

I have been playing around with the Google Maps API for the last few days and found it an amazingly simple way to display geographical data in your application. All you need to do is to reference the Google maps JavaScript file and a few lines of code would get you started with a basic map.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Google Maps API</title>
<!-- Google maps Script has to included -->
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key=YOUR_API_KEY_HERE" type="text/javascript"> </script>
<script type="text/javascript">
    function initialize() {
        var map = new GMap2(document.getElementById('map_canvas'));
        map.setCenter(new GLatLng(12.98058, 77.58854), 13);
    }
</script>
</head>
<body onload="initialize()" onunload="GUnload()">
<div id="map_canvas" style="height:500px;width:500px" />
</body>
</html>

There are a few things to note here

  • GMap2 is the object which returns the map object. We need to pass the DOM element on which the map has to be drawn. This is called the canvas and can be a div HTML element.
  • map.SetCenter: This method is the first that needs to be called on a map object in order to set its coordinates. In the code we passed the latitude, longitude and the zoom level of the map.
  • GUnload: Most important part of the application. Call this function in the onUnload event handler to avoid any unpleasant memory leaks in the application. This eliminates most of the circular references.

Now only displaying a map is not of much use. We need to be programmatically able to manipulate each part of the map in order to show our data in the canvas. This can be done through the Google Maps API which is an object oriented library representing each graphical part of the map.

For a small working example, I wrote some code to display data from an xml file on the server. Suppose you want to display the hotels on a map in Bangalore, and when the user clicks on the hotel, the details of the hotel should appear in a popup window. Something like this:-

The xml file resides on the server and contains all the details of the hotel including their latitude and longitude. The JavaScript gets the xml through an AJAX call and then iterates through to get the information of the individual hotels. For each one, it creates a marker and adds it to the map. Also using the details it creates the HTML to be displayed in the popup event and hooks up the click event handler to do it.
Below is the code:-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* ************************************************
* Developer: Ganesh Ranganathan
* Date: 26-Apr-2010
* Description: This is a Google Maps API Example.
* ***********************************************/
 
var map1;
 
$(document).ready(function() {
    //Init Method is run on load of Page DOM
    initialize();
    refreshData();
});
 
//GUnload method cleans up any google map1 objects
$(window).unload(function() {
    GUnload();
});
 
//The KeyValue pair for the location
//that we start with. Currently its bangalore
var DEF_LOC = {
'lat': 12.98058,
'lng': 77.58854,
'zoom':14
};
 
function initialize() {
    //Getting the map1 object. The [0] Index is because JQuery
    //returns an array of JavaScript elements from a DOM search
    //and we need only one
    map1 = new GMap2($('#map_canvas')[0]);
    //Setting the map1 to Bangalore and Adding standard map1 controls
    map1.setCenter(new GLatLng(DEF_LOC['lat'], DEF_LOC['lng']), DEF_LOC['zoom']);
 
    $.each([new GLargeMapControl(), new GMapTypeControl(), new GOverviewMapControl()]
    , function(index, value) {
        //Adding all the controls to the map
        map1.addControl(value);
    });
 
    //Setting the icon properties to display
    var hotelIcon = new GIcon();
    hotelIcon.image = "hotel_icon1.gif";
    hotelIcon.shadow = "http://chart.apis.google.com/chart?chst=d_map1_pin_shadow";
    hotelIcon.iconSize = new GSize(25, 34);
    hotelIcon.shadowSize = new GSize(35, 28);
    hotelIcon.iconAnchor = new GPoint(6, 20);
    hotelIcon.infoWindowAnchor = new GPoint(5, 1);
    markerOptions = { icon: hotelIcon };
}
 
function refreshData() {
    $.ajax(
{
    url: 'Hotels_data.xml', // Data Source in XML file
    //No Caching, Asynchronous call and setting the
    //Datatype to XML.
    cache: false,
    async: true,
    datatype: 'xml',
    success: function(xml) {
        //Successful ajax callback function. First clear
        //all existing markers to preserve memory
        map1.clearOverlays();
 
        $(xml).find('hotel').each(function() {
            //Iterating through each hotel tag in the xml
            //and gettiing the lattitude and longitude
            var lat = $(this).find('latitude').text();
            var lng = $(this).find('longitude').text();
            //pass node to helper function to get the markup
            //for the marker.
            var html = getMarkerHTML($(this));
            //Creating a marker object and assigning the click
            //event handler for the map to pan to the center of the
            //canvas. Also the Info window needs to open
            var marker = new GMarker(new GLatLng(lat, lng), markerOptions);
            GEvent.addListener(marker, "click", function() {
                map1.panTo(new GLatLng(lat, lng), DEF_LOC['zoom']);
                marker.openInfoWindowHtml(html);
            });
            //Add the marker to the map
            map1.addOverlay(marker);
        });
    },
    error: function() {
        //Error Callback. Just inform the user
        alert('An error has occured');
    }
});
}
 
//This is a helper function to get the markup
//for the marker's click node.
function getMarkerHTML(xmlNode) {
    //find the text in the childd nodes
    var get = function(tag) {
        return xmlNode.find(tag).text();
    };
 
    //Bolden the Key and append the value
    var decorateBold= function(key,value){
        return '<b>'+key+': </b>'+value+'<br />';
    };
 
    var singleCost = xmlNode.find('single_room').text();
    var doubleCost = xmlNode.find('double_room').text();
    var html = "<div style= 'background-color: #FFCC66;font-family: ";
    html += "Verdana;font-size: 1.0em;padding: 3px'>" + decorateBold('Name', get('name'));
    html += decorateBold('Address', get('address'));
    if(!isNaN(singleCost))
    html += '<b>Single Room: </b>'+ singleCost;
    if(!isNaN(doubleCost))
    html += '<b> Double Room: </b>'+doubleCost+'<br />';
    else
    html += '<br />';
    html += decorateBold('Phone',get('phone_no.'));
    html += decorateBold('Email',get('email'));
    html += decorateBold('Website',get('website'));
    return html+= '</div>';
}

Click here for the demo.

Jquery - The javascript magic bullet

Anyone who has written a fairly complex web application would have experienced the quirks of JavaScript. Though immensely powerful and probably the only way to write good client side code, JavaScript code can get difficult especially while doing complex DOM navigation and including cross browser support (Many browsers see the DOM differently).

The best possible solution to harness the power of JavaScript and making the code fun to write is to use client side libraries which do the dirty work for you. Arguably the most popular one available today is JQuery. It makes code both easy to read and write. Here are some cool things you can do with JQuery. To get started download jQuery at jquery.com, and reference the script file before any your custom scripts.

1
2
3
4
5
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<script type="text/javascript" src="Scripts/jquery.js" language="javascript" ></script>
<script type="text/javascript" src="Scripts/myscript.js" language="javascript" ></script>
</head>
  • Code which runs on page load: The classic way to do this was using the window.onload event. However, the onload event waits for all of the page to get loaded, including images. This can make the user wait for a long time before the events fire. jquery has an alternative – document.ready which fires as soon as the DOM gets loaded. In heavy pages, this can dramatically increase user experience
1
2
3
$(document).ready(function() {
    alert("Hello jquery");
});
  • Hooking up dynamic event handlers: Hooking up Javascript events was a pain. Now its surprisingly easy. Note how the document.getElementById has been replaced by the $. In this example we hook up a dynamic event handler for a button click event which gets the value from a textbox.
1
2
3
4
5
6
7
8
$(document).ready(function() {
    //Getting value of button and assigning an event
    //handler using an anonymous method
    $('#btnSayHello').click(function() {
        alert('Hello ' + $('#txtName').val());
    });
 
});
  • Animation made easy: Animation has always difficult in Javascript and pushed people towards Flash/Silverlight. JQuery’s animate API makes things almost too easy. In the example below, a div’s size is increased, its moved towards the left, made slightly transparent
1
2
3
4
<input type="button" id="btnAnimate" value="Animate" />
<div id="containerDiv" >
This is the text which would be animated
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$(document).ready(function() {
    //The animation is hooked on to
    //the Animate Button's click handler,
    //A callback function is specified to alert
    //when the animation is over
    $('#btnAnimate').click(function() {
        $('#containerDiv').animate({
            opacity: 0.6,
            marginLeft: '+=2in',
            fontSize: '3em'
        }, 1000, function() {
            alert('animation complete');
        });
    });
});
  • AJAXify your application almost instantly: Writing raw AJAX code was just too much of a hassle considering the time you spent on ironing out the browser differences rather than your core application logic. JQuery makes AJAX extremely simple and takes care of the background work of creating the xmlhttp object, making the call and giving you back the result. In the below example, I created a simple autocomplete textbox that makes the suggestions dynamically based on what you type. This would have taken atleast 150 lines if written in plain-ol javascript.

HTML Code

1
2
3
<span>Enter Country Name</span><br />
<input type="text" id="txtCountry" style="width:250px" /><br />
<span id="autoList" style="width:250px;display:block" />

Javascript code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
$(document).ready(function() {
    //Hooking the event handler to the keyup function
    $('#txtCountry').keyup(function() {
        //Only call AJAX function if atleast 3 characters are there
        $('#autoList').empty();
        if ($('#txtCountry').val().length > 2) {
            $.ajax( //Jquery AJAX api
        {
        url: "GetCountriesSuggestion.aspx",
        //Send in data as a query string
        data: "country=" + $('#txtCountry').val(),
        cache: false,
        async: true, //Make an asynchronous req
        datatype: "xml",
        //This is a callback function
        success: function(xml) {
            $('#autoList').empty();
            if ($(xml).find('Country').length > 0) {
                var ul = $('<ul></ul');
                //Creating a border and removing the bullets
                //that appear in an unordered list by default
                ul.css('border', 'solid 1px black').css('list-style', 'none');
                ul.css('left', '0px');
                //Find the country element and iterate
                //through each element
                $(xml).find('Country').each(function() {
                    //Creating a list item element and hooking up
                    //its click handler
                    var li = $('<li>' + $(this).text() + '</li>').css('cursor', 'pointer')
                    li.css('left', '0px');
                    li.hover(function() {
                        //This changes the color and background color
                        //of the suggestion box when the mouse is taken over it
                        //The hover method takes in two functions- one invoked on
                        //mouseover and one on mouseout
                        $(this).css('color', '#FFFFFF');
                        $(this).css('background-color', '#0000FF')
                    }, function() {
                        $(this).css('color', '#000000');
                        $(this).css('background-color', '#FFFFFF')
                    });
                    li.click(function() {
                        //Set the clicked item to textbox text and empty the
                        //Collecttion list
                        $('#txtCountry').val($(this).text());
                        $('#autoList').empty();
                    });
                    ul.append(li);
                });
                $('#autoList').append(ul);
            }
        }
    });
        }
    });
});

ASP.NET Code Behind in C#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
protected void Page_Load(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(Request.QueryString["country"]))
            {
                Response.Write(GetCountriesList(Request.QueryString["country"]));
            }
        }
        private string GetCountriesList(string countryName)
        {
            //creating a string builder object
            StringBuilder _response = new StringBuilder();
            XmlDocument _xDoc = new XmlDocument();
            //Load the xml file with all the countries
            _xDoc.Load(Server.MapPath("Countries.xml"));
            //Get all country names in the xml file
            XmlNodeList _allCountries = _xDoc.GetElementsByTagName("Entry");
            //Writing out xml declaration and root tag
            _response.Append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"yes\"?><Countries>");
            //Iterating through each country
            foreach (XmlNode _country in _allCountries)
            {
                //If what user entered matches the country name,
                //create a dynamic xml node and append
                if ((countryName.Length <= _country.FirstChild.InnerText.Length) &&( countryName.ToUpper().Equals(_country.FirstChild.InnerText.Substring(0, countryName.Length))))
                    _response.Append("<Country>" + _country.FirstChild.InnerText + "</Country>");
            }
            //Append closing root tag
            return _response.Append("<Countries>").ToString();
        }
    }