Tuesday, February 21, 2012

Mono for Android Pros & Cons

Updated 5/4/2013

Recently, I had the opportunity to develop a project using Mono for Android. For those of you who are unfamiliar with Mono for Android, it enables you to develop Android apps using a .NET language like C# instead of Java. Overall, I've had a good experience using Mono for Android and I'm happy with the results. I've created a handful of apps using Mono for Android and they've all been successful.

The Mono for Android API closely mirrors the standard Android API. For example, nearly all of the same classes, methods, and fields are present in both APIs. One of the main differences is that Mono for Android utilizes properties and delegates which are non-existent in Java. I liked how closely the two APIs were related since this made it easy to switch back and forth between them and to use the wealth of documentation that already exists for the standard Android API.

Below is a list of pros and cons regarding Mono for Android:

PROS

  1. Share Code Between Platforms - If used in conjunction with the Mono Touch API and the Windows Phone API you can potentially reuse your business logic code for both the iPhone and Windows Phone platforms. This is possible since everything can be coded using a single, common programming language instead of 3 different programming languages. Please note that this only applies to business logic code though; presentation specific code will be different for each platform because of differences in the APIs. In my mind the ability to reuse code is the single greatest benefit in using Mono for Android.

  2. Use Your Existing .NET Skills - If you or the majority of your team members are knowledgeable with a .NET language but not with Java then using Mono for Android may be appropriate. However, I think this advantage is somewhat diminished by the fact that C# and Java are so similar. There is probably a greater benefit in using Mono Touch since this eliminates the need to learn Objective C which poses much more of a learning curve than Java.

  3. The C# Language - In my own opinion, the C# language has several advantages over Java (comparing only the core language and not other aspects such as frameworks, community, etc). LINQ, lamdas, and delegates are some of the features I love most about C#. These features aren't irreplaceable but they save time and effort. Perhaps Java's position will improve when version 8 is finally released.

CONS

  1. 3rd Party Android Libraries - In general it's more difficult (but not impossible) to use 3rd parties libraries with Mono for Android. Since most Android libraries are written in Java they must either be rewritten in C# or invoked with JNI. Mono for Android version 4.2+ includes a Binding project that can automatically wrap Java code in a JNI wrapper. The Binding tooling automates much of an otherwise difficult process. However, there is still a learning curve and manual adjustments are often necessary.

  2. Bugs - There is a significant amount of bugs in Mono for Android. Well, perhaps significant is too strong a word, but it is definitely more stable to use Java vs. Mono for Android. Two of the most serious bugs I encountered are: DateTime.Now returns time in the wrong time-zone (UTC), and using a SSL connection with WebClient causes an exception. (I believe these bugs are fixed now). Here is a full list of outstanding bugs.

  3. Debugging - Using the Mono for Android debugger can be a frustrating experience. It sometimes causes your app to crash or skips breakpoints for unknown reasons. Usually I resort to logging and avoid the debugger altogether. Xamarin has tried to fix the debugger but the problem has persisted for over a year now.

  4. Other Limitations - A list of other limitations is available here.

Personally, I'd lean more towards using Java and the standard Android API rather than using C# and the Mono for Android API. I say this because, first, I have a strong background in Java, and, second, using Java will likely result in less complications and limitations. However the ability to share the same code between Android, iPhone, and Windows Phone is very tempting and may be a deciding factor in some cases. At my current job I am part of a team of Microsoft developers, so using Mono for Android is typically the preferred method for creating apps within that environment.

Below is the Mono for Android website:

http://xamarin.com/monoforandroid

Tuesday, December 13, 2011

CSS3 Decoration for Internet Explorer 6 - 9

I recently discovered a javascript library named CSS3 PIE. PIE makes Internet Explorer 6-9 capable of rendering several of the most useful CSS3 decoration features. The list currently includes border-radius, box-shadow, border-image, multiple background images, and linear-gradient as background image. The property that interests me most though is border-radius, since I hate having to create new images every time I want rounded corners with a different radius.

To get started with PIE download the files from their website (css3pie.com). The download includes multiple files but in most cases all you really need is the PIE.htc file. Copy the PIE.htc file into your web project and then reference it using the CSS behavior property. The behavior property is proprietary to Internet Explorer so all other browsers will ignore it. PIE uses the standard CSS3 border-radius property so you will need to add that too, as well as the -moz and -webkit versions for Firefox, Chrome, and Safari. Below is an example:

<html>
<head>

<style>
.rounded
{
 behavior: url(pie.htc);
 border-radius: 10px;
 -moz-border-radius: 10px;
 -webkit-border-radius: 10px;
 background-color: red;
 color: white;
}
</style>

</head>

<body>

<div class="rounded">
 TESTING
</div>

</body>
</html>

After adding PIE you should have CSS3 decoration support for all the major browsers with the exception of Opera although personally I never really consider Opera much anyways.

Note: I've noticed that PIE's rendering of rounded corners is quite slow in Internet Explorer. Because of this, I've decided NOT to use PIE on my blog, so anyone who is unfortunate enough to use Internet Explorer version 8 or lower will see squared corners instead of rounded corners. Upgrade your browser or switch to a better one.

Friday, November 4, 2011

Generic Method For Converting From DBNull

public static T FromDB<T>(object o)
{
   return o is DBNull ? default(T) : (T)o;
}

The method above is written in C# using generics. This method is used to cast weakly typed objects returned from a DataRow to strongly typed objects and it will automatically handle the conversion of DBNull. This method can also be used with nullable types which is convenient since capturing null values is often important when querying databases.

Below is a full example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            object i1 = 7;
            object i2 = DBNull.Value;
            object i3 = 3;
            object i4 = DBNull.Value;
            object i5 = "TEST";
            object i6 = DBNull.Value;

            int o1 = FromDB<int>(i1);
            int o2 = FromDB<int>(i2);
            int? o3 = FromDB<int?>(i3);
            int? o4 = FromDB<int?>(i4);
            string o5 = FromDB<string>(i5);
            string o6 = FromDB<string>(i6);

            Console.WriteLine("o1 = {0}", o1); //can't be null since its value type
            Console.WriteLine("o2 = {0}", o2); //can't be null since its value type
            Console.WriteLine("o3 = {0} {1}", o3, o3 == null ? "(NULL)" : "");
            Console.WriteLine("o4 = {0} {1}", o4, o4 == null ? "(NULL)" : "");
            Console.WriteLine("o5 = {0} {1}", o5, o5 == null ? "(NULL)" : "");
            Console.WriteLine("o6 = {0} {1}", o6, o6 == null ? "(NULL)" : "");
        }

        public static T FromDB<T>(object o)
        {
            return o is DBNull ? default(T) : (T)o;
        }
    }
}

The output would be:

o1 = 7
o2 = 0
o3 = 3
o4 = (NULL)
o5 = TEST
o6 = (NULL)

Saturday, September 24, 2011

Configuring Apache HTTP Server for PHP

First install Apache HTTP Server and then install PHP.

Next you must edit the httpd.conf file located in the conf directory of your Apache Install Directory. Add the follow lines to the end of the file (the lines may already exist; if so then verify they are correct and make any required changes):

#BEGIN PHP INSTALLER EDITS - REMOVE ONLY ON UNINSTALL
PHPIniDir "<PHP_INSTALL_DIRECTORY>"
LoadModule php5_module "<PHP_INSTALL_DIRECTORY>\php5apache2_2.dll"
<FilesMatch \.php$>
 SetHandler application/x-httpd-php
</FilesMatch>
#END PHP INSTALLER EDITS - REMOVE ONLY ON UNINSTALL

Replace the placeholder for the PHP Install Directory with a valid value and restart the Apache server. This example is specific to Apache 2.2 installed on Windows, so you may need to make slight tweaks if using a different version or operating system. See the following link for more information:

http://www.php.net/manual/en/install.php

Monday, September 19, 2011

How to Connect to DB2 with .NET

First you must install either the IBM Data Server Client or the IBM Data Server Runtime Client. The IBM Data Server Client has some additional developer tools but they are optional, so if you are searching for the most lightweight install then choose the IBM Data Server Runtime Client.

Next you must determine if a license is required. If you are connecting through a DB2 Connect Gateway then a license is not required, but if you are connecting directly to the DB2 Database then a license must be activated on the client computer.

To activate the license you must locate the db2conpe.lic file on your DB2 / DB2 Connect install CD. Once you have located this file, copy it to the client computer in the following directory: "C:\Program Files\IBM\SQLLIB\BIN" (location where your DB2 Client was installed). Now open a command prompt and change the directory to "C:\Program Files\IBM\SQLLIB\BIN" and execute this command: "db2licm -a db2conpe.lic". It should say that your license was successfully activated. You can verify this by typing "db2licm -l".

Now you are ready to start programming. Open Visual Studio and start a new console project. Before you start add a new reference (Project -> Add Reference) and browse to "C:\Program Files\IBM\SQLLIB\BIN\netf20\IBM.Data.DB2.dll".

Now copy and paste this code into your class file:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using IBM.Data.DB2;

namespace ConnectToDB2
{
    class Program
    {
        static void Main(string[] args)
        {
            string sql = "SELECT * FROM SYSIBM.SYSDUMMY1";
            DB2Connection con = new DB2Connection("Database=<DATABASE>;UserID=<USER_ID>;Password=<PASSWORD>;Server=<SERVER>:<PORT>");
            con.Open();

            DB2Command cmd = new DB2Command(sql, con);
            DB2DataReader reader = cmd.ExecuteReader();

            while (reader.Read())
            {
                Console.WriteLine(reader.GetString(0));
            }
        }
    }
}

Obviously replace the placeholders in the connection string with valid values.

Saturday, September 17, 2011

Client-Side Caching of Dynamic Content with Java

To achieve optimum performance and results when caching content you should try to set both the Expires header and the Last-Modified header.

The Expires should be set to a date in the future. It instructs the browser to cache the content until it expires when the Expires date is surpassed. If the content is very volatile (changes frequently) then the Expires date should be set to a lower value (near in the future) otherwise it should be set to a higher value (far in the future). This type of caching is referred to as "hard" caching because the browser never reconnects to the server again until the appointed time. Because of this, this type of caching is relatively fast.

The Last-Modified header should be set to a date in the past. It instructs the browser to cache the content unless it has been modified since the Last-Modified date was last set. If the content has since been modified then the Last-Modified date should be updated to a new value (the date the content was modified) to reflect this. This type of caching is referred to as "soft" caching because the browser always reconnects to the server again to check if the content has been modified. Because of this, this type of caching is relatively slow.

The Last-Modified header works in conjunction with the If-Modified-Since header. The first time the content is requested the server sets the Last-Modified date in the response. The browser then receives this response and caches the content along with the Last-Modified date. In subsequent requests the browser sets the If-Modified-Since date equal to the Last-Modified date that was previously cached. The server then receives the request and gets the If-Modified-Since date for the purpose of comparing it to the content's Last-Modified date.

The server is responsible for comparing the If-Modified-Since date and the Last-Modified date to determine if the browser has the most recent version of the content. If the dates are equal then browser already has the most recent version of the content and the server responds with an HTTP status code of 304 (Not Modified) which is the signal for the browser to reload the content from its cache. If the dates are not equal then the browser does not already have the most recent version of the content and the server responds by sending the updated content in its entirety along with the updated Last-Modified date.

When you combine the Expires header and the Last-Modified header the resulting behavior will be a hybrid of the two types of caches which will be the best in terms of both performance and flexibility.

Below is sample code that demonstrates how to set both the Expires header and the Last-Modified header in a Java Servlet. This Servlet makes use of the getLastModified method which automatically sets the Last-Modified date to the method's return value which is then compared to the If-Modified-Since date. Please note that the order in which the Expires header is set and the getLastModified method is called is important. The Expires header must always be set first which is why the service method is overridden for this purpose.

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.util.*;

public class CacheTestServlet extends HttpServlet
{
 private static long hits = 0;
 private static Date date;
 
 //This method sets the Expires date 15 seconds in the future
 //Typically the Expires date would be set to a higher value
 public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
 {
  response.setDateHeader("Expires", new Date().getTime() + 15000);
  super.service(request, response);
 }
 
 //This method updates the Last-Modified date on every other request
 //This is meant to simulate content that is modified occasionally
 //Typically the Last-Modified date would be retrieved from a file or database
 public long getLastModified(HttpServletRequest request)
 {
  hits++;
  if (hits % 2 == 1)
  {
   date = new Date();
   System.out.println("FULL HIT");
  }
  else
  {
   System.out.println("PARTIAL HIT");
  }
  
  return date.getTime() / 1000 * 1000;
 }
 
 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
 {
  response.getWriter().println("The current date & time is " + new Date());
 }
}

Below is a summary of the Servlet's output:

  1. The first time you load the page you will see the current date & time and the phrase "FULL HIT" will be printed.
  2. If you immediately reload the page, then the page will be reloaded from the browser's cache without reconnecting to the server. The date & time will not change and neither the phrase "FULL HIT" nor the phrase "PARTIAL HIT" will be printed because the server does not actually receive any requests.
  3. If you wait at least 15 seconds before reloading the page, then the browser will reconnect to the server to determine if the content has been modified but since the Last-Modified date has not changed it will reload the page from the browser's cache as opposed to reloading it from the server. The the date & time will not change but the phrase "PARTIAL HIT" will be printed.
  4. If you immediately reload the page, then the page will be reloaded from the browser's cache without reconnecting to the server. The date & time will not change and neither the phrase "FULL HIT" nor the phrase "PARTIAL HIT" will be printed because the server does not actually receive any requests.
  5. If you wait at least 15 seconds before reloading the page, then the browser will reconnect to the server to determine if the content has been modified and since the Last-Modified date has changed it will reload the page from the server as opposed to reloading it from the browser's cache. The date & time will change and the phrase "FULL HIT" will be printed.
  6. And so forth...

Tip: Pressing F5 in your browser will cause the browser to ignore any "soft" caches and reload the page. Pressing CTRL+F5 in your browser will cause the browser to ignore any "hard" caches and reload the page.

Here is a good link regarding caching:

http://code.google.com/speed/page-speed/docs/caching.html

Monday, July 25, 2011

X11 Forwarding

X11 forwarding enables the execution of a GUI (Graphic User Interface) program on a Linux/Unix server, even if the server is normally only available remotely via command line. This is accomplished by forwarding the display environment of the server to your localhost through an X11 tunnel.

Below is an example of how to enable and configure X11 forwarding on a Windows client:

  1. Download and install PuTTY. It is freely available for download here.
  2. Download and install Xming. It is freely available for download here.
  3. Start Xming if it is not already running.
  4. Start PuTTY and enter the Host Name or IP address of the server but do not connect yet. On the left, expand on the "Connection" node, expand the "SSH" node, and select the "X11" node. Check the box labelled "Enable X11 forwarding". Finally connect to the server by clicking the "Open" button.
  5. Once logged into the server, verify that the XAuth package is installed. The command to check the package will vary by Linux/Unix distribution. On Red Hat the command is "rpm -qa | grep xauth". The XAuth package is usually required for X11 forwarding.
  6. Install the XAuth package if it isn't already installed. Again the command to install the package will vary by Linux/Unix distribution. On Red Hat the command is "yum -y install xorg-x11-xauth". Root privileges are required to install the package.
  7. Verify that X11 forwarding is enabled in the file "/etc/ssh/sshd_config". Open the file and search for a line that reads "X11Forwarding yes". If the line is missing then add it; if the value is "no" then change it to "yes". Root privileges are required to open the file.
  8. Finally, execute the command that requires a GUI interface. After you execute the command Xming should launch the GUI program in a new window.