Category Archives: android

Migrating an application from Xamarin.Android to Kotlin

Disclaimer: this article isn’t about the why but more about the how and what.

Introduction

Earlier this year I was fortunate to be able to attend Google IO once again. One of the big announcements was that Kotlin was now fully supported by Google for use in Android. At IO17 I attended a few of the sessions on Kotlin and also did a few of the Code Labs and came away thinking this is a neat language. I started to think that it would be worthwhile to convert one of my applications over to Kotlin. This article details my experience in this process.

My Mobile Background

I started building native mobile applications in 2009, first on iOS in Objective C. In late 2010 I started looking at Xamarin as a cross-platform way to write mobile apps using C# as the language. I ported one of my apps from Objective C to Xamarin iOS. At that point I also needed to create an Android version of this application and rather than writing in Java I chose to use Xamarin Android (XA).  Although I have some experience in Java/JNI (dating back to 1995ish) in the WORA (write once, run anywhere) era I’ve never done a lot with Java. Since 2010 I’ve written many applications for clients using the Xamarin toolset.

One thing to point out in Xamarin development is that there are two major approaches to application development

  • write to the native APIs using a thin wrapper
  • use Xamarin Forms

For various reasons I have always written to the native APIs for both iOS and Android. This point is key as you will see it was a factor that made my migration easier.

The Project

The application I chose (a sports application) is only about 11k lines of C# code (this excludes the 7k line Resource.designer.cs file). Although many of you might consider this to be trivially sized, I believe this to be an good size for a first migration. Additionally this application also exercises various features including a local SQLite database, REST services, push notifications, administrative login and score input.

Getting Started

After I got back from IO17 I downloaded the alpha build of Android Studio 3 and created a test project and did the basic “Hello World” Android app. In order to learn Kotlin (besides googling and the Kotlin language website) I used these resources

I also was able to attend 2 other conferences which were helpful:

After the Hello World project I played around with a few of the templates in Android Studio and settled upon one that mimicked my application (drawer navigation). One key point:

Don’t try to get everything right initially—just go and start writing code initially so you can learn.

In other words during the early stages I suggest you write to learn, but plan on throwing it away. Don’t worry if it is good code. I used this approach for about 2 months (on a very part-time basis) while I tried out various things and extended the Android test app, Finally in July I created a new project that would eventually be the foundation of my production app

Porting

First off with the bad news:

You can’t be half pregnant

If you have an Android app written in Java you can start learning Kotlin by adding in new features in Kotlin. Conversely, in Xamarin this is an all or nothing endeavor. You’ll want to carefully weigh the number of lines of code and consider what third party components, libraries, etc. you are using and what you will replace them with.

The good news in porting from XA is that if you’ve written to the native APIs your resource files will work with no modifications. In addition, all of your Fragment and Activity lifecycle methods will match and so structurally your code will be very similar.

Note: If you’re wanting to port an application written in Xamarin Forms you will have a lot more work ahead of you. All of your layout files (XAML) will need to be redone using Android layout files. Additionally all of your C# MVVM code will need to be rewritten.

I chose to create the resources manually in Android Studio and then copy/paste the XML from XA into each resource file. I did this so that as I worked through the app I could look at the XML to make sure there were no parsing errors, etc.  I did find a few cases where I used attributes that were deprecated or just bad.

In most cases porting from C# to Kotlin is pretty straightforward.  Although there is no copy/paste converter for C# to Kotlin, I don’t find this to be a big loss. I do not recommend using a converter as you will learn more by converting your code manually.  I did find one occasion to use the Java to Kotlin converter when I needed to convert a Separated List adapter. Many years ago I ported it from Android to C#. I found it easier to go back to the original Java source code and use the Java to Kotlin converter and then modify it as appropriate.

One challenge I found was figuring out constants/enums, etc. as it seems like the Xamarin guys took some liberty in naming values and putting them in completely different namespaces from the Java/Kotlin namespaces. For example:

 

Another challenge I ran into was with asynchronous programming. If you’ve adopted C#’s async/await you’ll need to think about what approach you wish to use in Android. After attending the Kotlin Conference and watching Roman Elizarov’s sessions on coroutines I opted to use coroutines even though they are marked experimental. Note: Jetbrains is encouraging people to use coroutines in production; experimental is a misnomer in my opinion.

The following snippet is what I came up with–this example is one of the few cases where the Kotlin code was slightly more verbose than the C#.

Some of the components I used are listed below along with their Kotlin/Android equivalents.

 

Xamarin Kotlin
AndHUD Anko Indeterminate Progress Dialog
SQLite.net Anko SQLite
ServiceStack C# ServiceStack Android
Redth GCM.Client Firebase Cloud Messaging
Crypto Obfuscator Proguard
Azure Mobile Center Firebase Crashlytics

 

Technical Debt

Rather than port an outdated technology or piece of code I chose to address a few areas of technical debt by updating them to the latest technology.

  • Added in moderate use of Databinding
  • Updated Google Cloud Messaging (GCM) to Firebase Cloud Messaging (FCM). This also required a back-end server change as well.
  • Added notification channels (albeit just one)
  • Added Google Analytics (perhaps not considered technical debt but rather a feature)
  • Converted Icons to Android O Adaptive Icons

Are We There Yet?

Even after finally getting to feature complete I was reminded of this:

Hofstadter’s Law: It always takes longer than you expect, even when you take into account Hofstadter’s Law.

Some issues I ran into included dealing with

  • back stack and fragment crashes
  • manifest merge issues related to FCM and permissions. I had to use a setting to remove the merged attributes
  • crashes related to proguard
  • crashes related to errors in porting code (usually due to carelessness on my part)

A lot of hours were spent in testing and debugging code during the final phase.

Takeaways

As I write this now the Kotlin version of the application has been released to the Google Play store. Time will tell how well the port stands up with regards to maintenance, time to add new features, stability, etc.

This project took a total of 6 months. However, there were many weeks where nothing was done as this was a low priority project.

The Kotlin application is significantly smaller in both APK size and lines of code (LOC).

Xamarin Kotlin
11k LOC 4.4k LOC
APK 22MB APK 2.3MB

 

Some of you will look at that and wonder why the Kotlin LOC was so much smaller than the C#. Some of this was due to elimination of dead or commented out code. Another portion of code was in a shared library between iOS & Android and some of that shared code wasn’t being used in Android and so it wasn’t ported. C# POCO classes are a lot more verbose than Kotlin’s data classes (that amounted to about a 1K difference). I’ll have to do further analysis to figure out where the other differences were.

As for the APK size difference, the Kotlin APK was generated using Proguard while the Xamarin version did not. However, the Proguard optimizations only reduced the APK size by around 1MB in size. I believe the main size differences were to the number of DLLs that Xamarin includes in the APK. When you’re designing for the next billion every megabyte counts and this was a big win for Kotlin.

One other surprising benefit of the migration is performance–the Kotlin version is notably faster and I was not expecting that. The Xamarin version has never felt slow but next to the Kotlin version I found myself waiting longer for screens to load, etc.

All in all I’m pretty happy with how the application turned out. The Android Studio environment is also top notch. If you’re considering a similar migration I hope this article will be of help in making the decision to port or not to.

{360|AnDev} – A community Android developer conference in Denver

I just came back from {360|AnDev} and it was a great event.  Although I’ve been to several of the 360|iDev conferences (e.g. http://gerryhigh.com/category/360idev/) , this was my first time to the Android event. One thing that immediately stood out to me was the number of speakers from the mothership (Chet Haase, Yigit Boyer, Nick Butcher, Romain Guy, Andrea Falcone, Ben McCanny, Nicolas Roard, Doug Stevenson, Florina Muntenescu, Doris Liu et al). Conversely I’ve never seen a speaker from Apple at any of the iDev events.

As a side note, one thing I like about conferences in Denver is that the travel for me is pretty easy. From where I live (Kansas City) I can get a cheap non-stop flight and be here in an hour and a half. Additionally now that the airport has the train I can easily get from the airport to downtown for only $9 in about 30 minutes.  From the train stop at Union Station you can then catch a free bus (or walk) the several blocks to the hotel.

360AnDev was a 2 day event (Thursday/Friday, July 13/14 2017). This was just the second year of the event and the attendance was a little less than 200 attendees and 40+ speakers. Of the speakers almost 1/3 were women speakers (well done John, Chiu-Ki and Dave). There were 3 tracks with sessions running from 9-6 the first day and 9-5 the second day.  I thought all of the speakers were very good.

Having attended #IO17 this year and seeing the Kotlin sessions there it was nice to see that 360AnDev had 2 sessions on Kotlin. I attended both in part because I’m working on porting an app to Kotlin. It’s great to see the passion that the various speakers have for the language. Perhaps I’ll see a few of you at the Kotlin Conference in November.

I’ve posted links below to various slide decks and notes that people shared.  If you have other links that I missed shout out to me on twitter @gerryhigh and I’ll update this post.

If you’re a Android developer put this event on your calendar for next year and follow @360andev for updates (videos will be posted in the next few weeks is my understanding).

Gerry

 

 

Link to sample app for the session on Databinding (https://360andev.com/sessions/data-binding-in-practice/): https://github.com/google/spline

 

https://github.com/Esri/ecological-marine-unit-android/blob/master/AdventuresInOceanMapping.pdf

https://github.com/itrjwyss/360AnDev-2017/blob/master/Java8Features.pdf

Android Themes:
https://docs.google.com/presentation/d/1OAHEdeap6KTZLZwnWmJFAUjWmHzG2GxB_sKWhYnlO8s/edit#slide=id.p

 

Great notes by Kelly and  Chiu-Ki:

Migrating from Urban Airship to PushSharp

When Urban Airship (UA) announced back in June that they would be canceling their free tier for push notifications I started looking at other free & paid alternatives (e.g. Parse, Azure and others).  However, ultimately I decided to host the push notifications myself using PushSharp.

If you’re not familiar with PushSharp, it is a server side library for sending push notifications to various platforms.

The migration was really pretty easy and involved these steps:

  • Update server software that sends out push notifications to use the PushSharp libraries.
  • Update mobile apps (in my case this was just for the iOS and Android platforms)
  • Implement a mitigation strategy to handle users on old versions of the Android application

Updating Server Software

Urban Airship provides a REST API to send push notifications:

I replaced that code with something that looks like this:

If you look at the sample in the GitHub repository you’ll see there is some setup of the Push Broker that needs to be done prior to sending any messages.  If you are hosting your server code in a windows service you could put that in your main program.  In my case I’m hosting the Push Broker inside of IIS and thus have put all of that code into my Application_Startup method.

Note: you can update and deploy the server software prior to updating your apps.

A Note about Urban Airship notifications for Android

My sample code above includes a case for Urban Airship Android messages.  The reason for this is that the device token you get from their APIs is not actually a Google Cloud Messaging (GCM) device token but rather an Urban Airship generated token.  This is unfortunate as it means you’ll need to continue sending some push notifications via the Urban Airship REST API until all of your users are transitioned over to your new app.

Updating Mobile Applications

Updating my iOS application was pretty trivial as I just had to remove the code that registered my device with Urban Airship.  Nothing else needed to be changed as the device token you deal with is a standard APNS device token and not an Urban Airship token.  Additionally, as the messages that are sent by PushSharp on the server are identical to the messages sent via Urban Airship I didn’t have to change my code that parsed the notification.

Updating my Android app was a little more involved.

1.  Remove the Urban Airship binding library as well as any calls to Urban Airship.

2.  Add the GCM Client component to the project.

3. Edit the AndroidManifest.xml and remove all lines that deal with Urban Airship.

4.  Edit the startup application code (e.g. MainApplication.cs) and remove any calls to Urban Airship and replace with GCM.Client calls:

Old:

New:

 

4. Remove the BroadcastReceiver service and replace it with a service as shown in the GCM.Client sample.  Migrate any code from the OnReceive handler in the BroadcastReceiver class to the  OnMessage handler in GcmService.

One extra piece of work that I had to do was because I was using a Urban Airship specific class for displaying notifications (CustomPushNotificationBuilder). I replaced that with Notification.Builder.

Mitigation Strategy

To handle the fact that Urban Airship uses their own device tokens on Android, my approach was to treat device registrations using GCM.Client as a new device type on my backend (and thus leave in place Urban Airship GCM device registrations).  Thus until the end of the year my server software will continue to send push notifications to any users that are still on an older version of the Android app via the Urban Airship REST API.  Users that install the new application and subscribe for push notifications will receive their notifications via PushSharp.  I’ll continue to monitor how many devices are still on Urban Airship as I approach the year end and may choose to send a broadcast notification to those devices to tell them to upgrade.  After 12/31 I will update the server software to quit handling Urban Airship GCM tokens.

Final Thoughts

If you’re thinking about adding push notifications to your app but weren’t sure what to do take a look at PushSharp.  Jon Dick has done a great job with the software and continues to support and enhance it (he tells me he is working on a new and improved version that will be out before too long!)

Cross-platform Progress / HUD for Android and iOS with Xamarin

If you develop native mobile apps using Xamarin you quite likely have used BTProgressHUD for iOS or AndHUD for Android.  These are great components for displaying work-in-progress dialogs or toast messages.

While the components have similar APIs nevertheless they are different and in different namespaces and thus create an issue if you”re trying to code share between the two platforms.  I hit up Nic and Jon on twitter this week and Jon suggested writing a class that wraps both.

I wrote XHUD.HUD as a result.  It”s quite simple as it mimics the underlying APIs and unifies the slight differences between the 2 APIs.  However, I didn”t map every variation of the APIs and thus it will need to be extended.

An example usage is shown below:

 

Both Nic and Jon have added XHUD to their github repositories here: https://github.com/redth/andhud and https://github.com/nicwise/BTProgressHUD

Longer Term

Longer term it would be nice to see Xamarin.Mobile encompass more things like this.  Having said that it doesn”t seem like it is actively being developed.  So for now we have XHUD.HUD but I”m not crazy about the namespace XHUD as it seems redundant and too narrowly focused.  Perhaps XPlat as the namespace and it contains HUD, AlertDialog, etc? We”ll see.