Thursday, February 28, 2013

Common event handler mistake

Here is a mistake you may very easily make with dot42:

If you are using the onClick attribute of a button in a layout file like this:
<button android:layout_height="wrap_content" 
 android:layout_width="wrap_content" 
 android:onClick="OnButtonClick" 
 android:text="@string/Sum" />
Then you should use the EventHandler attribute to ensure the event handler is included:
[EventHandler]
public void OnButtonClick(View view) {}
Note that dot42 deletes all unreachable code to minimize the size of your APK.

Tuesday, February 26, 2013

How we minimize the size of your APK

The dot42 compiler compiles your C# code to an Android package (APK). This APK contains dex only. The dot42 compiler attempts to include only code that is actually needed in order to minimize the size of the APK. This is obviously desired for mobile devices (a design strategy you will find throughout Android).

This article explains how dot42 decides what code to exclude from the package.

Reachable detection phase

Before the dot42 compiler converts IL (or .NET code) to dex, it goes through a reachable detection phase. During this phase it marks types and members reachable if they can somehow be reached from one of the roots of the application. For example a method that is called from one of the roots is marked reachable. The same is true for methods that are called from methods that have already been marked reachable. This is an iterative process that ends after no new reachable code is found.

Less obvious are method overrides. If a virtual method Foo() is reachable, then all overriden Foo() methods of derived classes will be marked reachable. A similar rule applies to explicit method overrides used in explicit interface implementations.

A special case is a virtual methods that overrides a method in the Android framework. Even if this method is not being called from your code, it must still be marked reachable if the declaring type is marked reachable. For example if your derive from Activity and provide your own OnCreate method, you want your own OnCreate to be used and not the base implementation. So we should include it.

Other special cases include default constructors (because they are required by the Dalvik VM), class constructors (also known as static contructors) and explicitly marked methods (see next).

Key to the reachable detection phase is identifying the roots of the application. These are all public types of your assembly.

Explicitly marked types and members

There are situations in which a type or member is not reachable from your code per the rules above, but you still want to include it. Examples are a custom view that is referenced in your layout resource, use of reflection or because of (unit) testing. For such cases, dot42 has defined custom attributes that can be attached to a type or member.

The most important attribute is the Dot42.IncludeAttribute. By attaching it to a type or member, that type or member will be considered a root of the application. Example:
[Include]
void Foo() {}
This can also be done conditionally:
[Include(TypeCondition = typeof(SomeOtherType)]
void Foo2() {}
Foo2 method will only be marked reachable if SomeOtherType is reachable.

If you are using the onClick attribute of a button in a layout file like this:
<button android:layout_height="wrap_content" 
 android:layout_width="wrap_content" 
 android:onClick="OnButtonClick" 
 android:text="@string/Sum" />
Then you should use the EventHandler attribute to ensure the event handler is included:
[EventHandler]
public void OnButtonClick(View view) {}
By using EventHandler instead of Include, you protect it from being renamed.

See the dot42 API reference for more dot42 attributes that deal with event handlers and custom views.

Unit test types and methods

A final category that the dot42 compiler handles automatically are unit test types and methods. If you derive from TestCase, all methods named "test*" are automatically marked reachable. The same is true for methods that have an Nunit.Framework.Test or SetUp attribute attached to it. For example:
 /* included because its name starts with "test" */
public void testThisMethodIsIncluded() {}
/* included because of the Test attribute */
[Test]
public void ThisMethodIsAlsoInclude() {}

In doubt...

To know whether a type or member is included, you can use the dot42 ApkSpy to browse through the contents of your compiled APK. (See c:\program files\dot42\dot42ApkSpy.exe after installation.)

Localizing "RekenMaar"

One of the first, very basic dot42 apps is called "RekenMaar" (which is Dutch for 'let's do some math'). This app (written by my wife) lets children practice math. It is available on Google Play in both Dutch and English.

This articles quickly runs through the modification we made to the original Dutch version to make it localizable.

Localization

Originally, some strings were placed in a string resource file. Others were used literally in both code and layout resources. For example the layout for the settings contained a snippet like this:

<TextView
    android:id="@+id/OptionMultiplication"
    style="@style/ViewStyle_WrapBoth"
    android:text="Instellingen vermenigvuldigen
          en delen"
    android:layout_centerHorizontal="true"
    android:layout_margin="10dp" />

The android:text attribute contains a Dutch literal string. We changed it as follows:

<TextView
    android:id="@+id/OptionMultiplication"
    style="@style/ViewStyle_WrapBoth"
    android:text="@string/settings_div_mul_title"
    android:layout_centerHorizontal="true"
    android:layout_margin="10dp" />

The "@string/settings_div_mul_title" value is a resource identifier that refers to the following entry in the string resource file:

<string name="settings_div_mul_title">
    Instellingen vermenigvuldigen en delen</string>

Similar changes were made in code. For example the result checker contained this line:

tvResult.SetText("Goed");

This line was changed to:

tvResult.SetText(
    GetString(R.Strings.answer_correct));

with an entry in a string resource file:

<string name="answer_correct">Goed</string>

The final step in the localization process was to add a copy of the original Strings1.xml resource file and rename it to Strings1-en.xml. Obviously, this resource file holds the English translation. All nicely in one place.

By the way, if we would have renamed the Dutch resource file to Strings1-nl.xml and keep the English resource file as String1.xml, then English would have been the default.

Sunday, February 10, 2013

1.0.0.52 - What's new?

To get the latest version, run 'Check for updates'.


Fixed: Cannot start Emulator with special characters in username

If your username includes special characters (e.g. Cyrillic) then the emulator may not start. We introduced environment variable DOT42_AVD_HOME. Set this variable to an existing folder that does not have any non-ascii characters in it.

Fixed: Visual Studio 2012 crashes after each debug session.

This problem has been fixed in 1.0.0.52.

New: Publish free apps with Community Edition

Just a few days ago we changed our licensing model. After this change, the free Community License allows publishing free apps on Google Play or other public markets. Read more.

Fixed: Visual Studio 2012 crashed when editing Menu.xml

This problem has been fixed in 1.0.0.52.

Publish free app on Google Play

The Community License allows you to publish free apps on Google Play and other public markets. This post explains how you do this.

First of all, it is assumed that you already own a Community License and dot42 has been installed.

Use the right certificate

Let's start at the very beginning. After you have installed Visual Studio, you should have a dot42 project template as shown below:


After clicking OK, you must select or create a certificate:


The browse button (green) lets you browse for an existing certificate. If you use an existing certificate, then make sure that is has a lifetime of 30 years or longer. To generate a new certificate, click the create button (red). This will start the certification wizard. After filling out your personal details and selecting a password, the following panel is shown:


Make sure to select the option "Certificate will be used for publishing in public markets.".

If you now compile your application for the first time, it will show the following error:


This error is shown if you use a Community license and you did not request a free apps key yet. Next section describes how to do this.

Request Free Apps Key

If you login to your dot42 account and go to My Licenses you will see there is a line at the bottom: "To publish your app in a public market (such as Google Play) with the Community License, you must request a Free Apps Key."



Click the link as highlighted in the above image. This will take you to the following page:



This page asks you to provide two things: 1. the APK package name of your application and 2. the MD5 fingerprint of your certificate.

APK Package Name

The APK package name can be found on the Android tab of the properties of your dot42 Visual Studio project:


MD5 Fingerprint

When you compile your dot42 project in Visual Studio, the following is shown in the output pane:


Copy-paste the MD5 to the Request Free Apps Key page like this:



After you filled out the package name and the MD5 fingerprint of your certificate, you hit the "Request!" button. The next page shows you a code snippet like this one:

[assembly: Dot42.FreeAppsKey("hCIBgEyTYkEAQ7MGIzeaS7B1pRyMpqyqBymVWZV1mFkDM7Z28995" +
    "777333nvvvfe6O51OJ/ff/z9cZmQBbPbOStrJniGAqsgfP358Hz8" +
    "iHj8vpvmyyY/ML8dtWxeTdZs3R49P362KOmuLavn75Fl9tPv4buc" +
    "Tr8UX1bKdh03kI6/N0+w6bIEPHr/O6yIrjyY7+d69+w93p5Pzh7P" +
    "ze/cf39UvHr/hH8+ysskf35U/Hr+sq9l62p5Us/xoVrW759nbx3f" +
    "9Dx8fT9vikns52t15SOC8Dx6/Wi/bYuENNp3dW+0+aq9X+Wcf9b7" +
    "c+Sh9tyiXzS...............................6fPfrr5vRa" +
    "T6ezVVX1QP3nwez19uPzi4U/8dP6Tl9+9+/pp+9Xb3eNPdmZl+3u" +
    "1T64n85PZ/fV33n7y4Mnd5otnLyaT5fHrel3ufvLTrz69t6yevVx" +
    "/9/yn6oc/9fqTuxcv9u5+++m3380/md77srj89BcdPDuvf9Ey+6p" +
    "5vt9++vpNnR0/e7p6/RNv3xQ/9a787ieL1U+e/OTz7G72xbMv9k6" +
    "/evuDn3qx/PZPvjp+9xPVqn1ydfEZzYjF2w7r6P8B")]

Add this code snippet to your application and you are done!



Thursday, February 7, 2013

License Model Revisited

When we decided to go live with the dot42 technology preview, we were still figuring out how to create a simple license model. We didn't want to over complicate things. We wanted to offer a free version (for non commercial use) but also offer a license for those that did want to use the product commercially. We could say that the license model was thought out thoroughly and based on extensive research…. but for the large part it was gut feeling and a bit of guessing.

Since the launch we have received numerours feedback, not just about the product itself but also about the license model. Based on this feedback we made some decisions that are effective immediately.

Community License

Initially, the Community License did not allow you to publish your application on a public market place such as (but not limited to) Google Play or SlideME. This changes: The Community License now allows publishing free apps on a public market place.

As a technical note: To publish your app on Google Play, it must be signed with a certificated that has a lifetime of 30 years or more. To do this using the Community License, you will have to request an API key from dot42. We will update the docs and the software in the next days and post about it. 

What remains unchanged is that the Community License continues does not permit any form of commercial use.

Professional License

Initially, we set the price of the Professional License to 649 USD. We decided to lower it to 399 USD.


Tuesday, February 5, 2013

Why we cannot support Visual Studio Express

We have been asked to support the Express editions of Visual Studio. We have tried but failed. Here is why.

The dot42 Visual Studio Extension

The dot42 Visual Studio Professional (both 2010 and 2012) integration consists project templates, item templates and a Visual Studio package (VSPackage).

The templates are used to start a new project and add different types of dot42 items such as resources. The Visual Studio package makes dot42 actually do something in Visual Studio. This includes the dot42 project type, the debugger extension, additional property property pages, project item settings, and so on. For example, the debugger extensions is an implementation of a large set of COM interfaces (IDebugEngine2 and many more) that control what happens when you press F5.

So what about Visual C# Express?

As it turns out, Visual C# Express and all other Express editions are not extensible as required by dot42. The Express editions can only be extended by means of templates. You cannot control the compiler or the debugger.

Hopefully, further extensibility will be allowed by future releases of the Express editions. Until then, we can only support the Professional editions.

Sunday, February 3, 2013

dot42 1.0.0.48 - what's new?

API enhancements

Various .NET classes have been added or extended. Most notable are the additions in System.Text and System.Xml.Linq. We have added support for various Encoding classes and improved Load support on XDocument.

Improvements

Several exception in the System namespace are now directly mapped to their Android counterparts. For example System.SystemException maps to Java.Lang.RuntimeException and System.IndexOutOfRangeException maps to Java.Lang.IndexOutOfBoundsException.

Logging of deployment of apps to a device has been extended.

When the installation of an app on the device fails, we will try to recover and retry. For example when you change your certificate, dot42 will automatically uninstall the previous version and retry the installation.

The API documentation of the Android API has been improved. We will improve further in next releases.

Bug fixes

Several bugs in the dot42 compiler have been fixed. Also several minor issues related to custom styles with upper-case names have been fixed.

Saturday, February 2, 2013

Choosing between two API flavors

When writing an Android application in C# using dot42, the entire Android API and a large subset of the .NET framework API are available.

At the time of writing this article, coverage of the .NET framework API is far from complete, but this will improve over time. Coverage will however never be fully complete because some parts of the .NET framework simply don't make sense for Android. E.g. System.Windows that includes types for Windows Presentation Foundation will never be covered. A notable principle of dot42 is that we do not emulate Windows on Android. In fact, we don't want to emulate the .NET framework on Android. Our main aim is to offer the richness of C# and the comfort of Visual Studio to Android developers.

Even when the .NET framework coverage is almost complete, you as a developer will have both API's (Android and .NET) at your disposal. In some cases, it is an easy choice what framework to use. For example all Android related services, such as Activities or Android preferences, have no counterpart in .NET so the Android API is the only choice. The same is true for some parts of the .NET framework.

This article helps you choose between the two API's when the choice is not so obvious.

An example

The most obvious example of an arbitrary choice is a list of objects. The .NET framework provides System.Collections.Generic.List<T> and Android provides Java.Util.ArrayList<T>. Both give you very similar functionality such as adding, retrieving and removing objects by index. So which should you choose?

Benefits of choosing the Android API

The .NET framework implementation in dot42 makes extensive use of the Android framework. For example the List<T> type mentioned above is implemented using ArrayList<T>. This is done to minimize the extra code that has to be included in each APK.

But still, little code is more than no code. By choosing the Android API over the .NET API, you avoid  code in your APK that implements the .NET List. Due to the restricted memory on mobile devices, it makes sense to minimize extra code whenever possible. This results in smaller packages and faster code.

Benefits of choosing the .NET API

After outlining the clear benifits of choosing the Android API over the .NET API, you may wonder why we bother to support the latter. A strong case for using the .NET API is the reuse of existing code that originally targeted the .NET framework. Another good reason is that you are writing code that targets both Android devices and .NET centric devices and you want to maintain a single code base only.

But even if you are writing a new application that targets just Android, you may choose the .NET API because it's what you like and used before and therefore are more comfortable with.

Mixing both

Sometimes you want or have to use both API's. To make them fit together easier, we have added overloads and conversions methods to both API's.

For example, the IO part of the Android API, usually uses Java.Io.File to identify a file path. The .NET framework on the other hand uses a string to identify a file path. For this reason, we added a casting operator from Java.Io.File to string (as an extension of the Android API). This allows the use of Android functions resulting in a File object in combination with .NET functions. Here is a code sample:

void WriteSomethingInCacheDir(
        Android.Content.Context context)
{
  // Context.GetCacheDir() returns a Java.Io.File.
  // File.WriteAllText uses a string path as
  // first argument.
  File.WriteAllText(
        context.GetCacheDir(), // cast happens here 
        "Somecontent");
}

Final thoughts

We have argued that both API flavors have their own benefits. Therefore, we are committed to extending the .NET framework coverage. Also we will continue to add overloads and conversion methods that make it easier for you to mix both.