Showing posts with label MonoDroid. Show all posts
Showing posts with label MonoDroid. Show all posts

Thursday, September 22, 2011

Mobile Cross Platform MV Solution

After the initial hours lost on installing everything, I have been playing some more with MonoDroid lately, trying to port a basic Windows Phone 7 application to an Android device. Part of this was quite easy (thanks to MonoDroid that is) and part of it took some refactoring of the existing code. All in all, the experience was very insightful.

The existing WP7 application uses the MVVM pattern, which makes it very easy to get a separation of concerns between your model, view and viewmodel (I sometimes like to rant about this separation of concerns not being as clear as it should be in some applications). It also works very well in combination with the databinding that is provided in Silverlight. If you want to know more about the MVVM pattern, check out the article by Josh Smith in MSDN Magazine.

While MVVM works very well with Silverlight, WPF and Windows Phone apps, I did have some issues using this pattern in combination with MonoDroid. Let me walk you though this.

I started off thinking which parts of the existing code I would be able to reuse for the Android application. Reusing the views was out of the question, since Android views are written differently than Windows Phone views. But my models should be easily reusable, as should be my viewmodels.

The existing application already had the model and viewmodel classes in a separate Windows Phone class library. The views were contained in a Windows Phone 7 application (MemoChallenge.Wp7). So, reusing the models and viewmodels, would just be a matter of using this same class library for my Android application. Now, you can't just reference a Windows Phone 7 class library in an Android project. For this to work you need a second class library, specific for the Android/Monodroid project and some clever project linking.

For the Android application I actually created two more projects, one for the Android  views (MemoChallenge.droid), and one class library (MemoChallenge.droidlogic), which would be a linked project to the Windows Phone 7 class library (MemoChallenge.logic). You can use the Project Linker tool for this. This will link the two class library projects and will make sure that any change you do in one project, gets reflected in the other project.


After doing this, I immediately got my first compile errors, and they were abundant. Why did I get all these errors?

The thing is, viewmodel classes use commands all over the place. Or actually, they use the ICommand interface. This interface turned out to be quite a big problem. It is contained in a Windows specific dll, so the Android SDK does not know what to do with it.

To solve this problem, I could have rewritten the ICommand interface for Android. This would also mean I would have to add conditional compilation attributes all over the viewmodel code. I was not willing to do this, since it would be a lot of work. And I am not that fond of conditional compilation attributes.

Instead I used a combination of the MVVM and MVP pattern. I did not want to throw away the existing viewmodels, since they were working just fine. I did move them though, to the views project (MemoChallenge.Wp7), so they were no longer present in the shared class library. As a replacement for the Android application (and the WP7 application, remember these projects are linked), I added presenter classes. My viewmodels became very slim, I practically removed all of their logic and moved it all to the corresponding presenters. Now only thing my viewmodels had to do is forward the call to a presenter and we're done.

   public class GameViewModel : ViewModelBase, IGameViewModel 
   { 
     private ICommand _startCommand; 
     private ICommand _sameCommand; 
     private ICommand _notSameCommand; 
     private GamePresenter _presenter; 
     private IGameData _gameData; 

     public GameViewModel() 
     { 
       _presenter = new GamePresenter(this); 
     } 

     public ICommand StartCommand 
     { 
       get 
       { 
         if (_startCommand == null) 
           _startCommand = new RelayCommand(() => _presenter.Start(), 
             () => _presenter.CanStart()); 
         return _startCommand; 
       } 
     } 

     //rest of the code omitted 
 }  

I hope this gives you an easy way to get MVVM to work on Android/MonoDroid.

Friday, August 5, 2011

RTFM: First MonoDroid Steps

This will be a short post on my first experiences in using MonoDroid. It will primarily be a small list of the mistakes I made in getting a simple app to run on a configured device. This actually didn't work quite as easy as I thought it would.

I started with following the download and installation instructions for Visual Studio 2010 on the Xamarin site. Clicking all the SDK's and packages you need to download and installing all of those.

First error I made here is, they indicate at their site you need to install the Android SDK on a path with no spaces in it. This recommendation, actually, is one you should follow. If you install the Android SDK in the regular Program Files location, the Visual Studio plugin won't be able to find the SDK. That's the first mistake that made me have to reinstall the Android SDK.

After reinstalling the Android SDK, just check if the new path is filled out correctly under Tools - Options - Mono for Android in Visual Studio. If it is not, fill it out and restart your Visual Studio (and recheck if it is filled out correctly).


Another handy option here is the Adb logging option, which puts a log file on your desktop, so you can see a bit what's going on if things go terribly wrong.

That done, I tried to run the default project that's created when you start a new MonoDroid project. This failed miserably. I kept getting the error message that my activity could not be found: "Activity class {\} could not be found". I struggled quite some time with this error, figuring the mandroid process must have created an incorrect package name or maybe created an incorrect folder structure under my obj folder of the project. Whatever I tried, nothing worked:

  • renaming folders,
  • renaming the namespace, 
  • renaming the project, 
  • creating my own AndroidManifest.xml file
  • ...

After a lot of hair pulling and rereading the installation instructions and the first tutorial for the 100th time, my eye fell on the Java SDK version they recommended you download. You should install version 6, but if you click the link for downloading this, you get the download site for version 7. After uninstalling version 7, googling for version 6 and installing that one I finally could get the tutorial app deployed on an Android device.

Another error I thought I made along the way, is one I made out of laziness. While downloading the Android SDK I got tired by the size of the download, skipping it and only downloading the latest version (3.3 at the time of writing). And apparently MonoDroid doesn't support this latest version (yet). So installing revision 8 and configuring an Android device for this, made it all ok. But on the other side, deploying to the 3.3 version after I got revision 8 to work, went just fine. The only problem is that your UI gets stretched, because the 3.3 device is a tablet device. I still need to figure out how you can set op MonoDroid for bigger screens.

Tuesday, July 19, 2011

Cross Platform Mobile Development

At this years NDC conference, I followed a couple of talks about mobile development. It was announced there that the people behind MonoTouch and MonoDroid were moving to a new company named Xamarin. Well, as of yesterday, they have actually made the move and all sources for doing cross platform development can be found at their site.

They are actually providing a really cool way of doing cross platform development. You don't need to learn a whole lot of Objective-C or Java to develop applications for iPhone or Android, but you can develop in C# .Net, the language you use for doing Windows Phone 7 development. The only thing you still need to provide, that is specific for the iPhone and Android devices, is the user interface specific for each device. If you develop your applications wisely, though, - that is, using one of the MV* patterns - this is a walk in the park.

For iPhone development you will need a MAC, because the iPhone SDK only works on iOS. You can then install Mono and MonoDevelop (instead of Visual Studio) for OSX to start developing. For people like me, who are used to tools like ReSharper, you will, however, again need to learn how to type.

For Android development, the Java SDK is needed, and again MonoDevelop or Visual Studio 2010. With some handy project linking in Visual Studio, you can easily provide a shared code base for all three platforms. On this, watch the NDC talk, by Jonas Follesoe, about cross platform development!

The good news also is, that Xamarin offers both MonoTouch and MonoDroid as a free trial version that doesn't expire. The only drawback to the trial is that you can't deploy to actual iPhone or Android devices, only to their respective emulators. But this should be enough to get you started. Once you want to try out specific features the emulators don't offer (like gps, camera, ...) you will need to move to a paid license (or once you want to deploy to the marketplace, that is).

You will however need a little bit of extra effort if your initial WP7 projects are hosted on TFS. MonoDevelop for now does not offer a build in way for synchronising projects with TFS. You can use Microsoft Visual Studio Team Explorer Everywhere 2010, which offers a command line utility for connecting to TFS. Also SvnBridge gives you an SVN kinda way for connecting to TFS. And also, you could move your code base to SVN or GitHub (I love that place, not only for its name) alltogether.

This weekend there is also the MonoSpace conference in Boston going on, specifically for Mono development. They have a couple of sessions on mobile development as well. I hope they will put videos on-line of their talks.

Since I don't own a MAC (yet), I will try out the MonoDroid SDK in the next couple of weeks. Be sure to check back in to watch the progress (and the walls I will probably hit).