Wednesday, September 4, 2013

1.0.1.77 - What's new

To get the latest version, run "Check for updates" from the Device Center or download.

New: Added CancellationToken support to async.

Added CancellationToken class. Also added many methods overloads that use this type.

New: Added refresh function to Device center.

You can now scan for new devices from the Device Center.

New: Added copy to clipboard function to Assembly Checker.

If you encounter missing types or members, use this function to copy everything to the clipboard and paste it to an email for support.

New: 'Import res folder' in VisualStudio

The Android SDK requires a folder structure for your resources under a folder called "res". In dot42 you can put your resources anywhere in your project, and the filename contains resource qualifiers. You can now  import a traditional Android "res" folder into your dot42 project and all the conversions are done automatically.

Changed: Activation is started directly from installer.

At the end of the dot42 installation you will be asked to activate your license.

Changed: Removed support for creating/editing emulator images.

All support for creating and editing emulator images has been removed. We expect developers to either run a real device or use a virtual machine instead.

Changed: Replaced device connection wizard with online help.

No comments

Changed: Various UI improvements.

No comments

Changed: AtomicInteger/AtomicLong had a few incorrect properties.

The properties AndIncrement and AndDecrement have been removed.

Fixed: DateTime.ToString/ToShortDateString

Some format strings yielded incorrect  results.

Fixed: Add JAR reference missing from Visual Studio.

The "Add Jar reference" function was broken.

Monday, September 2, 2013

1.0.1.75 - What's new

To get the latest version, run "Check for updates" from the Device Center or download.
This release does not contain any new features. It fixes several issues found in the 1.0.1.74 release.

Fixed: Async on single CPU systems

The implementation of async may throw an exception or block execution on single CPU systems.

Fixed: Nested interface constants classes could be non-visible

Nested interface constants classes (e.g. ContactsContract.ISyncColumnsConstants) can be nested protected and as such not visible to you as a programmer. Now all such classes are public.

Fixed: Nested try/catch blocks with catch(object) are incorrect

Sometimes the C# compiler generates a try/catch block with a catch(System.Object) handler. If you combine that with a catch(System.Exception) handler, the order of catch handlers becomes invalid.
Now all catch(System.Object) handlers are compiled as catch-all handler, solving the order issue.

Fixed: Some local variables do not appear in Locals window

In the Locals windows of the debugger, some local variables of large methods do not appear as expected. This was related to register spilling.

Saturday, August 31, 2013

Running Android 4.3 in Hyper-V

To make testing easier, we wanted to run Android on our desktop. Because we develop on Windows 8, the obvious choice is to run Android in Hyper-V, since that already comes with Windows 8. In this post we describe how we did it and what we found.

Get started

There is a ready made iso image available on android-x86.org. We want the latest, so we choose the Android-x86-4.3-devel image from July 25.

Next,  we create a Hyper-V standard virtual machine without any OS settings that has the following specifications:

  • 1 CPU
  • 512MB memory
  • 32GB virtual harddisk (a bit large, but who cares)
  • Legacy Network Adapter connected to an external virtual switch
  • DVD mapped to the downloaded iso image

Installation

We fire up the virtual machine and the following boot screen appears:


We select the Installation option. Next, several questions are asked, mainly about harddisk partitioning. We create a single partition for our entire virtual harddisk and make it bootable. The installation completes quickly afterwards.

First start

When we run Android for the first time, this boot screen appears:


We let the timer run out and continue with the boot process. The root prompt appeares for a short period, after which the the graphical environment shows up:


Since this is the first time, we have to go through the standard Android first time settings such as user accounts, WiFi and so on. Since we have connected to a (virtual) legacy network adapter, we skip the WiFi part. Finally we reach an empty but familiar homescreen:

Deploy and Run dot42 apps

Now it is time to deploy and run a dot42 app on our fresh virtual Android. We use the dot42 Device Center to connect to a networked device. We use Settings - About - Network on the virtual machine to get its IP address and enter that in the dot42 Device Center.


After that the virtual machine is visible in the Device Center and we can develop with it. We take the SpinningCube sample and here is how it looks:


It ran pretty smoothly, atleast a lot better than in the emulator.

Tips and tricks

Here are a couple tips and tricks we found out in the process:
  1. Bamboo tablets do not work as mouse in Android inside Hyper-V, we had to connect a normal mouse instead.
  2. Pressing Alt-Left or Alt-Right when inside Android-X86 will switch between the graphical UI and the root console.
  3. One time we had to reset the virtual machine after Android went to sleep. We tried all recommended key combinations, but nothing worked. After that we used the developer setting in Android to prevent sleeping.



Tuesday, August 27, 2013

How we implemented Async/await

You can now use async/await with dot42. This valuable language construct lets you write elegant code that looks exactly like synchronous code, but works asynchronously.

Example:

namespace AsyncAndroid
{
  [Activity]
  public class MainActivity : Activity
  {
    protected override void OnCreate(Bundle savedInstance)
    {
      base.OnCreate(savedInstance);
      SetContentView(R.Layouts.MainLayout);

      var myButton = FindViewById<Button>(R.Ids.myButton);
      myButton.Click += myButton_Click;
    }

    private async void myButton_Click(object sender, EventArgs e)
    {
      var status = FindViewById<TextView>(R.Ids.txtStatus);
      status.Text = "Waiting...";

      await Task.Factory.StartNew(() => DoSomethingLongRunning());

      status = FindViewById<TextView>(R.Ids.txtStatus);
      status.Text = "I'm back";
    }
  }
}

The above code implements a simple button click that starts a lengthy job and updates a text view to reflect the status. The click will always be handled on the UI thread. Doing something lengthy on the UI thread is a bad idea. With the await keyword, the method will return directly (to the UI thread) while the lengthy job is started on a background thread. When the lengthy job is ready, execution is resumed (on the UI thread).

To achieve the same with traditional threads, background workers, AsyncTasks, Loader's etc. you would be writing much less readable code.

Configuration changes

A problem that is specific to Android, is that of configuration changes. By default your activity will be destroyed and restarted when a configuration change happens. For example rotating your device will (by default) result in a new activity instance. This is fine unless you have a long running activity on some thread.

Let's say you want to download a large image and show the content in an ImageView afterwards. You typically start a background thread to download the image and pass the activity instance and perform a callback after the download has finished. However, if the activity was destroyed and recreated in the meantime (because of a configuration change), the callback will show the downloaded image in an ImageView that has been disconnected. The new activity instance will not show the downloaded image.

The same is still true if you use the following code:

var webClient = new WebClient();
var data = await webClient
                     .DownloadDataTaskAsync(myImageUrl);
var imageView = this.FindViewById<ImageView>(R.Ids.MyImage);
imageView.SetImageBitmap(DecodeBitmapData(data));

The async/await in the above code will ensure that execution resumes on the current UI thread, but not on the correct Activity instance (this.FindViewById will be invoked on the old activity instance).

To solve this problem, we have extended the Task API. Let's take a look at the same code and see how it works.

var webClient = new WebClient();
var data = await webClient
                     .DownloadDataTaskAsync(myImageUrl)
                     .ConfigureAwait(this);
var imageView = this.FindViewById<ImageView>(R.Ids.MyImage);
imageView.SetImageBitmap(DecodeBitmapData(data));

The additional call to ConfigureAwait(this) ensures that after await you will return on the original thread AND the this pointer will point to the latest activity instance.

To make this work you must add this line of code to the OnCreate method of your activity:

SynchronizationContext.SetSynchronizationContext(this);

Note that only the this pointer is updated. If you would hold on to an imageView instance before the await and use it after the await, you would still be updating the wrong instance of imageView.

Task scheduling

When you start a new Task, the scheduler decides what thread executes that task. In dot42 the task scheduler follows the following rules:
  1. Normal tasks will execute on a thread from a thread pool. By default this thread pool reserves multiple threads. In future versions we will refine this.
  2. Code following an await will continue on the thread that started the awaited task (even if the task was started inside asynchronous code). This may be refined in future versions.
  3. Tasks created with a LongRunning option will always execute on a new thread.
  4. Tasks created by Async methods in the dot42 .NET framework implementation (such as WebClient.DownloadDataTaskAsync) will run on threads of a seperate IO thread pool. This ensures that slow IO tasks will not be able to block your short running normal tasks.


1.0.1.74 - What's new

To get the latest version, run "Check for updates" from the Device Center or download.

New: Async/await support

You can now use the C# 5 async/await keywords to create much cleaner asynchronous code.
Besides supporting most of the System.Threading.Tasks types, we took it a step further and helped you solve a nasty problem in Android: working with asynchronous code in combination with configuration changes. For more info, read this blog.

New: PropertyInfo support

Added support for using properties in combination with reflection. Metadata for properties is only added to the APK if you actually use the PropertyInfo class. Otherwise no such metadata is created to minimize the APK size.

New: Several new samples

New samples demonstrate async/await and Google maps (thanks to Brush Smith). We ported Kilobolt from the Android game tutorial.

Change: Installer name and installation folder

The installer has been renamed from dot42Setup.exe to dot42AndroidSetup.exe. Application folders and registry keys have been renamed similarly. For future extensibility.

Improved: Enum performance

Mathematics with enums were rather slow at runtime. This has been improved significantly.

Fixed: AssemblyChecker tool misses forwarded types

All types of the .NET framework are implemented in dot42.dll. Type forwarders make sure these types are found in the dot42 counterparts of the original assemblies such as mscorlib.dll, System.dll etc. The AssemblyChecker tool missed many of these type forwarders. This resulted in false warnings.

Fixed and Improved: XDocument

Some whitespace/element sequences did not result in correct XText and XElement sequences.
Several missing members of the XDocument API have been added.

Fixed: Lots of compiler issues

Most fixes are related to structs and generics (or a combination of them).

Fixed: Debugger did not show full class hierarchy.

The "Locals" debug window allowed you to view members of a class and its base class, but no those of the base class of the base class and so on.

Friday, July 26, 2013

1.0.1.72 - What's new

To get the latest version, run "Check for updates" from the Device Center or download.

New: Android 4.3 API

We've added support for the new Android 4.3 API. To use it, all you have to do is update dot42 and to set your Android version to 4.3.

New: Custom application types

It was not possible to specify a custom Android.App.Application derived class in the <application> section on your Android manifest.
We've altered the ApplicationAttribute such that it is now also allowed on classes as well (and not only on assemblies). If you want to make a custom Application class, create a class derived from Android.App.Application and attach an [Application(...)] attribute to it. In that case you may not use the ApplicationAttribute at assembly level.
We've added a sample that demonstrates this new feature. See OS\CustomApplication.

Friday, July 5, 2013

1.0.1.71 - What's new

To get the latest version, run "Check for updates" from the Device Center or download.

Beta version

As of this release, we consider the product beta. That means that we are very close to being feature complete for the full 1.0 release.

What we will add before the full release is:
  • System.Threading.Task support
  • More samples
  • Better documentation

New: Visual Studio 2013 Preview support

dot42 now supports the preview version of Visual Studio 2013.

New: Struct behavior support

The copy semantics of structs are now supported.

New: WCF JSON services (client) support

Earlier versions added support for WCF XML based services. This version adds similar support for JSON services.

Fixed: Could not set breakpoint in delegate

If was not possible to set breakpoints in a delegate method.

Fixed: Error removing breakpoints in Visual Studio

Removing a breakpoint in Visual Studio caused a "One or more breakpoints could not be deleted" error.

Fixed: Cast error in Visual Studio 2012 XML Editor

Using an XML editor in Visual Studio 2012 could result in cast errors.

Fixed: MetaDataAttribute.Resource property has wrong type

This property was of type int. Now it is of type string.

Fixed: Various unsigned short/byte errors

Fixed various compile time and runtime errors.

Fixed: Various verify and compilation errors

Fixed many unrelated compile time and runtime (verify) errors.

Fixed: Imported java methods with generic parameters fail

No comment.

Fixed: Rare typing error in code of imported java methods

In rare cases IINC instructions used in java code resulted in compilation errors.

Changed: System.Object.Wait methods renamed to JavaWait

These methods are not in the .NET API but did conflict with other methods in the .NET API.

Changed: All C# types now implement java.lang.Cloneable

With this change you can safely call Object.MemberwiseClone without having to implement additional interfaces.

Changed: Significant compiler performance improvement

Various profiling sessions resulted in better compilation performance for both very large methods and packages with a large number of methods.

New: Various framework types/methods have been added

No comment.



Tuesday, June 25, 2013

Google+ and dot42

The Google+ platform for Android lets you authenticate a user with the same credentials they use on Google every day. Once a user signs in with Google, you can create more engaging experiences and drive usage of your app.

Download sample from GitHub.

Create a new Google+ project

It is assumed that you have dot42 with either Visual Studio 2010/2012 Pro or SharpDevelop installed.

If you create a new project and want to add Google Play Services to your project, you can do this by checking the library in the New Project wizard:


You will notice that when you check Google Play Services then Android Support Library will be checked automatically because it is required.

After hitting OK, you will be asked to accept the Android SDK License agreement:


After hitting I agree, your new project is created. If you expand the Reference node in the Solution Explorer, you will see that references to both dot42.AndroidSupportLibrary.dll and dot42.GooglePlayServices.dll have been added:



Register your app in the Google APIs Console

Before you can run your app on a physical device, you need to register your app in the Google APIs Console as follows:

(the following is partly copied from https://developers.google.com/+/mobile/android/getting-started, Step 1. but modifed for dot42)

1. In the Google APIs Console, create an API project for your application.

2. In the Services pane, enable the Google+ API and any other APIs that your app requires.

3. In the API Access pane, create an OAuth 2.0 client ID by clicking Create an OAuth 2.0 Client ID:

a. Type a product name in the dialog box that displays, and click Next. Providing a product logo and home page URL are optional.

b. Choose Installed application as your Application type and select Android as type.

c. In the Package name field, enter your Android's app's package name. You can find this on the Android tab of your Visual Studio project properties dialog.


d. Make sure the Output view is visible and compile the project. Copy the SHA1 fingerprint from the output view:


e. Paste the SHA-1 fingerprint into the Signing certificate fingerprint field.

f. To activate interactive posts, enable the Deep Linking option.

g. Click the Create client ID button.

Google+ Sample

The Google Play services package includes the Google+ sample located in <android-sdk>/extras/google-play-services/samples/plus. We have taken this sample, ported it to C# and made it run as a dot42 app. View it on GitHub.




Android SDK Manager and JDK


Unfortunaly, the JDK from Oracle and the Android SDK Manager are not part of a single coordinated install and getting them to work together can be frustrating sometimes.

Until now, dot42 required the Android SDK Manager if you wanted to download and import packages such as Google Play Services.

The SDK Manager, in turn, requires the JDK from Oracle. My experience with identifying the appropriate JDK version on the Oracle site and installing it is far from painless.

After it has been installed, getting the Android SDK manager to run properly is the next hurdle. On different machines I discovered that I had to either Run as administator. Or if that didn't work, I had to run the android.bat batch from the Android SDK tools folder instead, or I had to tune my PATH environment variable. I have also found myself uninstalling and installing different versions and editions of the JDK just to see what combination would work. The high number of up votes of related questions and answers on StackOverflow is testimony to this problem.

For the purpose of dot42, this effort seems unproportional high given the minor role of the Android SDK manager and especially that of the JDK (we don't use it to parse or generate Java - we do that ourselves).

So, as of 1.0.0.70, we have decided to do offline imports of libraries such as Google Play Services and the Android Support Library and bundle them as DLLs with dot42. You import them by just checking them in the New Project Wizard:


Note that these DLLs are just wrappers to bind with C#. At runtime, your APK will call directly into the corresponding APK or use the original Java code compiled to DEX.

We consider this a first step towards making dot42 more self-contained and realize that there may still be occasions where you need the Android SDK Manager. But we strive to remove this requirement if possible.

Friday, June 21, 2013

1.0.0.70 - What's new

To get the latest version, run "Check for updates" from the Device Center or download.

New: 9-patch image support

It is now possible to use 9-patch images (.9.png) as drawable resource. We have extended the Widgets\UsingButton sample to demonstrate this.

New: Portable Class Library support

It is now possible to reference Portable Class Libraries in your dot42 project. To accomplish this, all dot42 assemblies had to be made retargetable and the assembly name of mscorlib.dll has been fixed.

New: Easier use of Support and GooglePlayServices libraries

The new application project wizard has been extended with checkboxes to import commonly used libraries. Currently, these include Android Support Library and Google Play Services.


Note that you will be asked to agree with the corresponding license agreement.

New: Samples are now on GitHub.

As of this release, our samples are on GitHub for easy access. The samples will also be installed locally at [My Documents]\Dot42\Samples folder.

New: Added Google Plus sample

We have ported the Plus code sample that is included with Google Play Services client library. See on GitHub.

Fixed: Dragging xml files into Visual Studio causes crash

No comment.

Fixed: Step behavior of debugger is broken

Line number information in the DEX files was broken. This resulted in unexpected step behavior in the debugger.

Fixed: Various compiler issues

Various minor issues have been fixed in the IL to DEX compiler.

Fixed: HttpWebResponse may loose data

The underlying HTTP client was closed prematurely. Make sure to close your HttpWebResponse to avoid socket and memory leaks.

Monday, June 17, 2013

dot42 and Parse

Parse allows you to store your app's data in the cloud. The Parse Quickstart let's you create a basic Parse Android app in minutes. We will walk through this Quickstart and make the necessary changes to make it work with dot42. It is assumed that you have signed up with Parse.

Create new dot42 project

First, create a blank dot42 Application Project from Visual Studio 2010 Professional, Visual Studio 2012 Professional or the SharpDevelop edition that is included in the dot42 download.


Parse Quickstart Guide

Login to your Parse account. If you haven't created an app yet, then Parse will make it very obvious how to do so. So I assume your first app as been created. Click 'Quickstart Guide' right after creating your app or click 'Quickstart' at the top of the dashboard.


Let's go through the Quickstart Guide as it appears on the Parse web site and take all the analog dot42 steps. We will number the steps similarly so it should be easy to match the Quickstart steps.

First you must choose your platform. Make the following selections: Android, Native and Existing project.




1. Download the SDK

Follow the "SDK files for existing Android projects (.zip)" link.

2. Import the zip file's contents into your existing Android project

Create a libs folder inside the dot42 project that we created at the very start. Copy "Parse-1.3.0.jar" from the zip archive the to the libs folder.

Right-click the Project node and select 'Add Jar Reference...".


The following dialog shows:


Browse to "Parse-1.3.0.jar" in the libs folder and hit OK. Reload the project if prompted. Compile the project to verify that the import went fine. The reference should now have been added like this:


3. Add the following using statement to your Activity:

using Com.Parse;
Call Parse.initialize from your onCreate methods to set your application id and client key:
Parse.Initialize(this, 
   "k1DM1............................d9RyrVu", 
   "etaQb............................SJfz7Yh");
Make sure to copy your own keys here! Also notice how the Initialize is captitalized.

4. Request appropriate permissions

Your app must request the "INTERNET" and "ACCESS_NETWORK_STATE" permissions:
[assembly: UsesPermission(
   Android.Manifest.Permission.INTERNET)]
[assembly: UsesPermission(
   Android.Manifest.Permission.ACCESS_NETWORK_STATE)]

5. Track statistics around application opens

Add the following to the onCreate method of your main Activity:
ParseAnalytics.TrackAppOpened(GetIntent());


After installing the SDK, copy and paste this code into your app, for example in your Application.onCreate:
ParseObject testObject = new ParseObject("TestObject");
testObject.Put("foo", "bar");
testObject.SaveInBackground();
Run your app. A new object of class TestObject will be sent to the Parse Cloud and saved. When you're ready, click the button below to test if your data was sent. It should look similar to this:





1.0.0.69 - What's new

To get the latest version, run "Check for updates" from the Device Center or download.

Improved: Import Jar References

Importing jar files has improved greatly. The visibility of types and members now resembles the java semantics more closely. The renaming of types and members (in case of name conflicts) is done more predictable and safer. As a result, many jar files that caused issues such a Parse, gdx and google-play-services now import correctly. It does however mean, that in rare cases you have to change a type/member name manually.

New: Import Jar preserves annotations when possible

Annotations placed on java types and members are now preserved in dex when possible. As of this release, all constant values for annotations are supported. Enum and array values are not yet supported.

New: Various .NET framework enhancements

These include support for regular expressions, various IO types such as BinaryWriter/Reader and lots of other small additions. Also various bugs in the framework implementation have been fixed.

Fixed: Lots of compiler issues

A large number of issues have been fixed in the compiler. These issues are both in the compilation phase (the compiler gives an error) and at runtime (typically a verify error is raised).

Fixed: Various debugger issues

Various minor issues in the debugger have been fixed.

Change: License agreement must be accepted during activation

The license agreement is no longer part of the installation. Instead the license agreement must be accepted when dot42 is activated (serial entered).

Fixed: Various SharpDevelop issues

Projects created in SharpDevelop could not be loaded in Visual Studio. We have also fixed various minor user interface issues in the SharpDevelop integration.

Saturday, May 18, 2013

A WCF Client of a RESTful service - XML

Version 1.0.0.68 introduces WCF support. This allows you to write a WCF client of a REST/XML service. We will add JSON support in a future release.

While this article includes code snippets only, the full code sample is included with dot42. Install dot42 and then open the sample from [MyDocuments]\dot42\Samples\Network\WcfTodoService. The solution includes both a server (project TodoServer) and a client (project ClientApp).

Compile and run the server

The server is a Windows application. It can be found as project TodoServer in the WcfTodoService solution. Compile this app and run it with administrator rights. When you run it, it shows the following dialog:


Start the service by hitting the 'Start Service' button. If you did not start the service with admin right, it will show you the following error:


To start with admin rights, compile the project and navigate to TodoServer.exe in folder \Network\WcfTodoService\Server\bin\Debug. Right-click the executable and select 'Run as administrator'. When you start the service, you should now see this:


The service uses port 9222, so make sure your firewall allows connections to it.

Shared files

The client and the server projects share the following files (these are in the WcfTodoService\Shared folder):
  • TodoApi.xsd
  • ITodoApi.cs
  • TodoApi.cs (auto generated from TodoApi by xsd.exe)
TodoApi.xsd and ITodoApi.cs together make up the API specification of the REST service. ITodoApi.cs is the service contract file. It defines an interface and has WCF attributes applied. TodoApi.cs is generated using the following command:
xsd.exe /c /n:Dot42.TodoApi.Version_1_0 TodoApi.xsd
This generates classes from TodoApi.xsd that provide a rich object model for regular XML data.

Client

The client is a dot42 project and will run on your Android device. The UI code is really straightforward and in order to focus on WCF, we will skip it and discuss the code that invokes the service.

The programming model is exactly the same as with traditional WCF, except that one option in the project properties has to be checked. With this option checked, dot42 will generate proxy classes for the service so there is no need to generate code at runtime.


All WCF client code in MainActivity.cs use WebChannelFactory to open a channel to the service and make requests to the underlying methods exposed by the contract:
private const string _hostAddress = 
  "http://192.168.1.1:9222/RestService/TodoService";

private VersionType GetVersion()
{
  using (var client = new WebChannelFactory<ITodoApi>(
    new WebHttpBinding(), new Uri(_hostAddress)))
  {
    client.Open();
    var channel = client.CreateChannel();

    using (new OperationContextScope((IContextChannel)channel))
    {
      return channel.GetVersion();
    }
  }
}
If you run the client on your Android device it will look like this:

The full code

While this article includes code snippets only, the full code sample is included with dot42. Install dot42 and then open the sample from [MyDocuments]\dot42\Samples\Network\WcfTodoService.

Friday, May 17, 2013

Integrating dot42 with SharpDevelop

With this post, we share our experiencies with integrating dot42 with SharpDevelop (#Develop from here on).

What version?

First we had do decide what version of #Develop we wanted to integrate with. There were two choices: Version 4.3 is the current stable version and therefore the obvious candidate. Version 5 is the upcoming version and currently in preview state. Looking at the future, it made sense to choose version 5. However it is still in preview state and even though we believe it is already quite stable, we did experience several crashes. Also, we don't know when version 5 goes into beta or RTM so we decided to choose 4.3. We tested with both versions and we expect to quickly upgrade to version 5 once it has stabilized.

Custom build or stock version?

With an IDE like Visual Studio this is a simple choice because there are only stock versions and everybody uses those. #Develop, however, is open source so we may choose to do a custom build. Because we want to minimize the maintenance load on our team, the initial approach was to extend a stock version using the standard addin model of #Develop. Doing so we ran into several issues. Especially, extending the debugger forced us to change this approach. We still use the stock 4.3.1 code base, but we had to remove the debugger addin. We also decided to integrate the entire IDE into our own setup. This makes it easier for us to test our integration because we know the exact version and we avoid potential problems in the field with existing #Develop installations.

The dot42 addin

#Develop is a highly extensible platform. It consists of a small core that has a namespace tree and an addin system. An addin extends the functionality of #Develop. The namespace tree is used to extend all kinds of functions like menus, debuggers, project types etc. An addin is implemented by an xml file (.addin) and usually one or more assemblies. The addins are automatically loaded from the AddIns folder.

Parts of the dot42 addin is a dot42 specific project behavior (this is similar to a project sub type in Visual Studio). To add this project behavior, we had to write one C# class and include the following snippet in our .addin file:

<Path name="/SharpDevelop/Workbench/ProjectBehaviors">
  <Condition
         guid="{337B7DB7-2D1E-448D-BEBF-17E887A46E37}"
         name="ProjectBehaviorSupported">
    <Class
         class="Dot42.SharpDevelop.Dot42ProjectBehavior" 
         id="Dot42ProjectBehavior" />
  </Condition>
</Path>

This snippet registers a class (Dot42.SharpDevelop.Dot42ProjectBehavior) in the namespace tree under the well known path "/SharpDevelop/Workbench/ProjectBehaviors". The Condition element ensures that the dot42 project behavior is used only when the project has the sub type identified by the given guid.

Next to the project behavior, the dot42 addin contains a debugger, various "pads" (UI elements) for the debugger, menu items, XML editors and more. All of these are integrated into the #Develop platform using Path elements in the addin file.

What did we encounter?

The addin system and namespace tree make it easy to extend #Develop but it lacks an important feature: you cannot remove or alter existing elements. For example we wanted to remove several menu items that are added by the stock debugger addin. This is not possible. More precisely, we wanted to add an additional condition to those menu items so they would be hidden for a dot42 project subtype. This is also not possible. A solution to this problem would be to modify the stock addin files, but that was something that we wanted to avoid. We posted a suggestion the #Develop forum to extend the core of #Develop to make this easier in.

We ran into another issue. Implementing our own debugger was a matter of implementing the simple interface IDebugger as published by #Develop. However, the standard debugger UI (pads for running threads, call stacks, local variables, etc.) assumes that the current debugger is always of type WindowsDebugger. Even worse, the UI crashes if this is not the case. For this reason, we had to remove the stock debugger addin and build our own UI pads for threads, call stacks, etc.

Breakpoints were a lot easier. These are special kind of bookmarks and by just querying the BookmarkService we quickly found BreakpointBookmark. We could use it as is without doing anything special to toggle them in the UI.

To wrap up

It has been a pleasure to integrate dot42 with #Develop. After the many many many hours we spend digging through tons of COM interfaces that make up Visual Studio, it is an absolute delight to extend an IDE that is fast and has all the sources available.

Hopefully we can help the #Develop team to improve their platform.

Thursday, May 16, 2013

1.0.0.68 - What's new

To get the latest version, run "Check for updates" from the Device Center or download.

New: SharpDevelop integration

As of this release dot42 includes a SharpDevelop integration. This is an option of the setup.

The SharpDevelop integration consists of a dot42 project type, project and item templates, a debugger and a designer for simple resource files such as strings and menus (not the layout).

We support the same functionality in SharpDevelop as we do in Visual Studio except for IntelliSense with XML files. We will add this in a future release.

New: WCF client support

You can now build a WCF client of a REST/XML service. The programming model is exactly the same as with traditional WCF, except that one option in the project properties has to be checked. With this option checked, dot42 will generate proxy classes for the service so there is no need to generate code at runtime.

We have added a code sample (Network\WcfTodoService) that demonstrates this new functionality. Don't forget to consult the readme of this sample because some configuration is required to get the REST/XML service running and accessible.

We will add support for REST/JSON services in a future release.

Changed: Setup warns about missing Visual Studio

If you do not have Visual Studio 2010/2012 Professional installed, the setup will warn you and instruct you to install SharpDevelop.

Fixed: Various casting problems

Various casting expressions (e.g. long to byte) could cause verify errors.

Fixed: Various enum conversion problems

Some conversions from enum to number expressions could cause verify errors.

Fixed: Various import jar problems

Several (java) jar files caused problems either at import time, build time or runtime. These jar files include files for the OUYA console, Google mobile ads and Google services.

Fixed: Breakpoints and step behavior are not precise

Setting a breakpoint at a specific location did not always result in an actual break. Stepping through the code in the debugger also showed some unexpected behavior. All of this was related to an incorrect mapping between source code line numbers and dex instruction offsets. This has been fixed resulting in a much better debugging experience.

Fixed: Local variables have incorrect name in debugger

Local variables had numbers appended to their names while debugging. Now the original variable names are used. This also fixes the problem when hovering over a variable during debugging. It now shows the variable value as a tooltip.

Monday, May 6, 2013

C# Lambda Expressions

A lambda expression is an anonymous function that you can use to create delegates or expression tree types. By using lambda expressions, you can write local functions that can be passed as arguments or returned as the value of function calls. See Lambda Expressions (C# Programming Guide).

Lambda expressions are supported by the dot42 compiler. The Calculator code sample demonstrates the use of lambda expressions by creating handlers voor de button click events.


While this article includes code snippets only, the full code sample is included with dot42. Install dot42 and then open the sample from [MyDocuments]\dot42\Samples\Various\Calculator.

Handling the button click event

The click event of the add, subtract, multiply and divided buttons are all handled by the same method Calc but per button instance a different argument is passed:
protected override void OnCreate(Bundle savedInstance)
{
  ...

  btn = (Button)FindViewById(R.Ids.cmdAdd);
  btn.Click += (s, x) => Calc(Operations.Add);
  btn = (Button)FindViewById(R.Ids.cmdSub);
  btn.Click += (s, x) => Calc(Operations.Sub);
  btn = (Button)FindViewById(R.Ids.cmdMul);
  btn.Click += (s, x) => Calc(Operations.Mul);
  btn = (Button)FindViewById(R.Ids.cmdDiv);
  btn.Click += (s, x) => Calc(Operations.Div);
}

private void Calc(Operations operation)
{
  Calc();
  this.operation = operation;
  leftOperand = rightOperand;
  rightOperand = 0;
  FormatValue();
}
Note that without lambda expressions, you would either have to define a different method per button or the operation (+, -, *, /) would somehow have to be encoded in the event source.

Friday, May 3, 2013

1.0.0.67 - What's new

To get the latest version, run "Check for updates" from the Device Center or download.

Changed: Enum types are now implemented as instances.

Before this version enum types were implemented as their underlying primitive type. Typically, an enum was implemented as an int (value type). This has been changed. Now enums are implemented as object instances as in Java. The reason is that we could not distinguish between enum parameters and primitive type parameters. So both method Foo(int) and method Foo(MyEnum) were compiled to Foo(int) causing a verify error.
This change is handled by the dot42 compiler. It does not require any change in your code.

Improved: Device Center usability.

The Device Center has been simplified by removing the Home tab and removing all unnecessary ribbon buttons.

Improved: Many .NET framework members added.

Lots of .NET members have been added to existing types and new types have been added. This includes types in System.Net and System.ComponentModel.

Fixed: Java classes using SomeType<Void> cause verify errors.

In Java it is allowed to use Void as a type argument for generic parameters. This is not supported in C#. When a Java jar file is imported into C#, all Void type arguments are converted to Object.

Fixed: Nullable enum types cause verify error.

This has been solved as part of the above enum change.

Fixed: TearDown attribute on NUnit tests not supported.

The TearDownAttribute attribute has been added and is used as expected in NUnit test cases.

Fixed: Various minor compiler issues

Lots of small (often unreported) compiler issues have been fixed.

Coming soon...

We are getting close to releasing support for the SharpDevelop IDE.

Monday, April 22, 2013

1.0.0.65 - What's new

To get the latest version, run "Check for updates" from the Device Center or download.

Fixed: Support4Demos sample fails to compile with Community edition license

The Community Edition postfixes the application label with " (by dot42.com)". This conflicts with using a resource ID for the application label. This has been fixed in the code sample (it now uses a literal).

Improved: Improved performance of the dot42 compiler

Various performance improvements.

Saturday, April 20, 2013

1.0.0.64 - What's new?

To get the latest version, run "Check for updates" from the Device Center or download.

New: Reference any Java library

Until this version we only supported referencing a jar file (java library) that acts as a stub for an Android package (APK) that is already on the device. In this version we introduce support for referencing any Java library. This includes the Android support library. This is a major step indeed.

For convenience, we have added assemblies for the Android support library so that you do not have to download it yourself. Just add a reference to dot42.AndroidSupportLibrary.v4.dll (or dot42.AndroidSupportLibrary.v13.dll) and you are ready to use the entire support library.

We ported the Support4Demos code sample that comes with the Android support library to C# to demonstrate the use of this library. See <MyDocuments>\dot42\Samples\Various\Support4Demos.

New: Improved framework support

We added support for several .NET types (including System.TimeSpan) and improved and fixed the support of many base types such as System.Double and System.Float. With these improvements come various compiler fixes related to structs. Note that this does not mean that structs are now fully supported.

New: Improved Android manifest support

We added support for the <provider> element of the AndroidManifest.xml file by means of the Dot42.Manifest.ProviderAttribute. Attributes of he <provider> element correspond to properties of the ProviderAttribute.

Previously, all manfiest element attributes that were defined in an Android version later than the minimum Android version of your project, were not available as properties of the corresponding attributes in the Dot42.Manifest namespace. Using them resulted in a compile error. As of this version, all properties are now available. This allows you to use newer properties if you set your target SDK version beyond the minimum version. Note that you cannot use properties beyond your target SDK version.

New: Improved ApkSpy

The opcodes of instructions in both dex files as well as java files are now visible in the Apk Spy:


Change: Target SDK version 

The previous version added a property on the PackageAttribute to set the Target SDK version. This property has been removed. You should now specify the Target SDK version in your Visual Studio (MSBuild) project. Go to the project properties and select the Android tab to change this version.


Change: Android framework interfaces starting with 'I' 

Few interfaces in the Android framework follow the .NET interface naming pattern of INameOfInterface. Previously, these interface were prefixed with an 'I' like all other interfaces resulting in a double II. As of this version, these interfaces are no longer prefixed with an additional 'I'. For example Android.Os.IIBinder is now Android.Os.IBinder.

Fixed: ADB installation task did not report all possible installation errors

It does now.

Fixed: Enum types with underlying type other than int causes verify errors

The following line caused a verify error:
public enum MyEum : sbyte {...}
This has been fixed.

Fixed: Many small compiler issues

While adding support for java libraries (and testing this) we ran into many small compiler issues. We fixed those.

Monday, April 15, 2013

Call a JSON Web Service

This article demonstrates how to consume the Airport Service of the Federal Aviation Administration using the standard Android HTTP client API and the standard Android JSON parser. The FAA offers a tutorial describing their web services.

While this article includes code snippets only, the full code sample is included in dot42 update 1.0.0.61 or higher. See folder [MyDocuments]\dot42\Samples\Various\AirportInfo.

Send a GET request to the Airport Service

To get the airport status for airport OAK, including known delays and weather data, you would make a GET request to the following URL:

http://services.faa.gov/airport/status/OAK?format=application/json

The above URL encodes two input arguments: First, the three letter airport code (in this case OAK). Second, the format of the data that you would like to get back (in this case JSON).

The following code makes this request:
string iataCode = "OAK";
var uri = string.Format("http://services.faa.gov/airport/status/{0}?format=application/json", iataCode);
var client = AndroidHttpClient.NewInstance("AirportInfo");
var request = new HttpGet(uri);
var response = client.Execute(request); // send the request

Parse the HTTP response

When the above request is made to the service, it will return a response consisting of plain text formatted according the JSON format. Android offers class JSONObject to parse the name/value pairs.

First, we must extract the JSON string from the response:
var content = response.GetEntity().GetContent();
var reader = new BufferedReader(new InputStreamReader(content));
var builder = new StringBuilder();
string line;
while ((line = reader.ReadLine()) != null)
{
  builder.Append(line);
}
string jsonString = builder.ToString();
Then we wrap a JSONObject around the string:
JSONObject json = new JSONObject(jsonString);
And now we can query named values like this:
string state= json.GetString("state");
string city = json.GetString("city");

The full code


The full code sample is included in dot42 update 1.0.0.61 or higher. See folder [MyDocuments]\dot42\Samples\Various\AirportInfo.