MONODROID: Una valida alternativa .NET per sviluppare con Android

Introduzione

In questo articolo cercheremo di introdurre un modo alternativo allo sviluppo di applicazioni Android, utilizzando la potenza della tecnologia .Net come alternativa a JAVA. Ci focalizzeremo sui vantaggi e sugli svantaggi nell’utilizzare uno strumento diverso da JAVA, cercando di capire quali benefici si possono acquisire.  Con lo sviluppo di dispositivi mobili sempre più potenti, le aziende, non solo quelle legate all’intrattenimento, ma anche quelle nel mondo enterprise cercano di trovare un posto di comando nel rispettivo mercato.  In questo mondo concorrenziale, molte volte  ciò che ci distingue è l’applicazione che rendiamo disponibile. Un’azienda cerca sempre di avere le proprie applicazioni sulle principali piattaforme presenti in commercio: ANDROID, IOS, WINDOW PHONE che dispongono di un sistema operativo e di un modello di sviluppo totalmente differente l’uno dall’altro. Con Android sviluppiamo in JAVA, con IOS sviluppiamo in Objective C o XCode mentre in Windows Phone  in C#. Figure professionali distinte, non tutte le realtà aziendali possono permettersele ed è difficile ma soprattutto costoso, avere le competenze necessarie a coprire tutte e tre le piattaforme. Pensiamo ad un’impresa dove il core business è focalizzato su un settore diverso dall’informatica e dove ogni investimento, specialmente in questo momento di crisi e’ sempre fatto col contagocce.  Ma allora come possiamo concorrere con aziende che hanno l’opportunità di investire e quindi avere tutte le applicazioni su tutti i dispositivi? Semplicemente cerchiamo di riciclare il codice ed utilizzare qualcosa che ci possa aiutare in questo. Unsupporto è dato dalla XAMARIN e dalle sue alternative che permettono di sviluppare su tre piattaforme utilizzando .NET, proponendosi quindi a noi sviluppatori che lavoriamo con Visual Studio, programmiamo con C# e sviluppiamo già sulle tecnologie basate su XAML, come Window Phone.

Quello che ci permette di fare XAMARIN e’ di condividere le librerie comuni con le tre piattaforme e di riscrivere solamente la parte di frontend senza dover riscrivere il nostro codice ma adattandolo alle varie piattaforme (risparmio di tempo e di costi) ed inoltre non dobbiamo avere nel nostro team tre figure professionali differenti.

Cerchiamo di capire meglio con un esempio. Utilizziamo quello più famoso al mondo e più utilizzato: il TweetSearch.

TWEETSEARCH

Per non riscrivere codice,  utilizzeremo l’esempio del nostro amico Sigurd Snørteland che ci ha accompagnato durante tutti i nostri incontri e le nostre conferenze permettendoci  ogni volta di utilizzarlo.

Il tweetSearch e’ un’applicazione che consente di visualizzare tweets e ricercali sui nostri dispositivi mobili.

Prima di tutto creeremo uno strato comune a tutti i dispositivi:

Il nostro oggetto

public class Tweet
    {
        public DateTime Published { get; set; }
        public string Title { get; set; }
        public string Author { get; set; }
    }

E la nostra classe di search

public class Searcher
    {
        private string _baseSearchUrl;
        private static XNamespace _namespace = "http://www.w3.org/2005/Atom";

        public Searcher(string baseUrl)
        {
            _baseSearchUrl = baseUrl;
        }

        public void Search(string query, Action<IEnumerable<Tweet>> callback)
        {
            var searchClient = new WebClient();

            searchClient.DownloadStringCompleted += (sender, e) =>
            {
                IEnumerable<Tweet> results =
                    XElement.Parse(e.Result)
                        .Descendants(_namespace + "entry")
                        .Select(entry => new Tweet()
                        {
                            Title = (string)entry.Element(_namespace + "title"),
                            Published = DateTime.Parse((string)entry.Element(_namespace + "published")),
                            Author = (string)entry
                                                .Descendants(_namespace + "author")
                                                .First()
                                                .Element(_namespace + "name")
                        });

                callback(results);
            };
            searchClient.DownloadStringAsync(new Uri(_baseSearchUrl + Uri.EscapeDataString(query)));
        }
    }

Per ogni dispositivo dobbiamo scrivere l’interffaccia grafica.

Per Android sara’:

[Activity (Label = "tweet search", MainLauncher = true)]
    public class ButtonActivity : Activity
    {
        List list = new List();
        Android.Widget.Button btnSearch;
        TextView lblTwitter;
        EditText txtSearch;

        private List photo_ids = new List() { Resource.drawable.bird };

        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);
            SetContentView(Resource.layout.main);

            ImageView btnSearch = FindViewById(Resource.id.btnSearch);
            btnSearch.SetImageResource(photo_ids[0]);
            btnSearch.Click += new EventHandler(btnSearch_Click);

            txtSearch = FindViewById(Resource.id.txtSearch);
            lblTwitter = FindViewById(Resource.id.lblTwitter);
        }

        void btnSearch_Click(object sender, EventArgs e)
        {
            if (list.Count == 0)
            {
                Twitter twitter = new Twitter();
                twitter.twitteSearchCompleted += new EventHandler(twitter_twitteSearchCompleted);
                twitter.search("nnug");
            }
            else
            {
                foreach (TwitterObject twitter in list)
                {
                    lblTwitter.Text += twitter.Date.ToString() + System.Environment.NewLine + twitter.Title + System.Environment.NewLine + System.Environment.NewLine;
                }

                list = new List();
            }
        }

        void twitter_twitteSearchCompleted(object sender, EventArgs e)
        {
            list = (List)sender;
        }
    }

Mentre per Window Phone l’interfaccia e’:

 public partial class MainPage : PhoneApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        #region UI

        private void txtSearch_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                this.Focus();
            }
        }

        private void txtSearch_LostFocus(object sender, RoutedEventArgs e)
        {
            search();
        }

        private void lboTwitte_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            lboTwitte.SelectedIndex = -1;
        }

        private void imgSearch_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            search();
        }

        #endregion

        #region Twitter

        private void search()
        {
            lblLoading.Visibility = Visibility.Visible;
            lboTwitte.Opacity = 0.3;

            Twitter twitter = new Twitter();
            twitter.twitteSearchCompleted += new EventHandler(twitter_downloadCompleted);
            twitter.search(txtSearch.Text);
        }

        private void twitter_downloadCompleted(object sender, EventArgs e)
        {
            List list = (List)sender;
            lboTwitte.ItemsSource = list;

            lblLoading.Visibility = Visibility.Collapsed;
            lboTwitte.Opacity = 1;
        }

        #endregion
    }

Infine creeremo l’interfaccia per IPhone con Monotouch

    public partial class MainPage : UIViewController
    {
        #region Constructors

        // The IntPtr and initWithCoder constructors are required for items that need
        // to be able to be created from a xib rather than from managed code

        public MainPage (IntPtr handle) : base(handle)
        {
            Initialize ();
        }

        [Export("initWithCoder:")]
        public MainPage (NSCoder coder) : base(coder)
        {
            Initialize ();
        }

        public MainPage () : base("MainPage", null)
        {
            Initialize ();
        }

        void Initialize ()
        {
        }

        #endregion

        #region UI

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            lblTwitter.Text = "";
            txtSearch.ShouldReturn = delegate
            {
                txtSearch.ResignFirstResponder();
                search();

                return true;
            };

            imgSearch.TouchUpInside += HandleImgSearchTouchUpInside;
        }

        void HandleImgSearchTouchUpInside (object sender, EventArgs e)
        {
            search();
        }

        #endregion

        #region Twitter

        private void search()
        {
            Twitter twitter = new Twitter();
            twitter.twitteSearchCompleted += twitter_downloadCompleted;
            twitter.search(txtSearch.Text);
        }

        void twitter_downloadCompleted (object sender, EventArgs e)
        {
            List list = (List) sender;
            BeginInvokeOnMainThread (delegate {

                foreach(TwitterObject tweet in list)
                {
                    lblTwitter.Text += tweet.Date.ToString() + Environment.NewLine + tweet.Title + Environment.NewLine + Environment.NewLine;
                }

            });
        }

        #endregion
    }

1
WindowPhone

2
Iphone

3
Android

Conclusioni

In questo esempio si è potuto osservare la semplicità di riutilizzo del codice, riscrivendo solo la parte frontend, ciò reso possibile dall’utilizzo della potenza grafica di ogni device.

Il 14 novembre è stata pubblicata un comunicato di un accordo tra Microsoft e Xamarin, che porterà ad un pieno supporto di Visual Studio 2013 per le portable class libraries (PCL), potendo quindi avere librerie trasparentemente adoperabili in progetti iOS, Android, Windows Phone e Windows Store.

La partnership comporta anche un’offerta speciale per i possessori di abbonamenti MSDN (anche se non tutte le forme di abbonamento MSDN sono eleggibili per lo sconto Xamarin) e corsi online gratuiti.

Naturalmente ci saranno altre novità sul lato della programmazione, inoltre un supporto di Microsoft  renderà migliore tutta la parte di integrazione tra dispositivi…

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...