こんにちは この記事では、モバイルアプリケーションの作成を学んでいるが、この分野でまだあまり進歩していない初心者デベロッパーと私の経験を共有したいと思います。 具体的には、「ネイティブ」.NETプラットフォーム(Windows Phone 7およびWindowsデスクトップアプリケーション)とモバイルプラットフォーム用の.NETの移植バージョンの両方で動作するポータブルコードの作成方法とアプリケーションの設計方法を教えてください。 MonotouchやMonodroidなど。
MonoおよびPortable Class Libraryについて少し
移植可能なコードを正しく記述する方法を詳細に理解するには、最初に.NETがiOSおよびAndroidでどのように機能するかを理解する必要があります。 このトピックは非常に大きいので、ウラジミールウラジミロヴィッチが言うように、簡単に説明します。
モノタッチ
iOSのMonoは次のように機能します。JITコンパイラもiOS自体の.NETもありません。 .NET実装全体を含むすべてのコードは、完全にすべて、ネイティブバイトコードにコンパイルされ、アプリケーション配布パッケージと「接触」します。
ここから、次の「長所、短所、水中レーキ」が続きます。 さらに、パフォーマンス(ネイティブコードは定義により高速です)。 マイナス番号1:アプリケーション配布パッケージのボリュームは少なくとも6 MBです。 マイナス2:残念ながら、Silverlight 4プロファイルのみが移植されており、それでも完全ではありません。
主な驚き:ジェネリックも反射もありません。 そのため、コレクション、WCFのカスタムプロキシクラス、WPFのデータバインディングを使用したゲームはありません。
モノドロイド
Androidの.NETについては、次のことを言う必要があります。一見しただけでは、すべてがそんなに悲しいわけではありません。JITとジェネリックがあります。 ただし...ジェネリックは劣っています(パラメータークラスはJava.Lang.Objectから継承する必要があります)。JITは正確にはJITではありません。 Habrasocietyがこのトピックに興味がある場合は、ここで別の記事のトピックを強調表示することもできます。
ポータブルクラスライブラリとWindows Phone 7
C#を使用する最も広い可能性は、もちろん、マイクロソフトのモバイルプラットフォームです。 特に彼女のために、Silverlightのバージョンが開発されました。 ただし、Windows Phone用にコンパイルされたアセンブリは、デスクトップアプリケーションでは機能しません。 これは理解できますが、非常に不便ですが、ターゲットプラットフォームはまだ異なります。
Windows Phoneと完全な.NET間のコードポータビリティを適切にサポートするために、Portable Class Library(PCL)プロファイルが実装されました。これは、.NETの公式バージョンをサポートするすべてのプラットフォームに存在する基本クラスのセットです-Windows、Metro、Windows Phone、Silverlight、Xbox。
ニュアンス
Mono *用に開発する場合、3.5までの完全な.NETバージョン用にコンパイルされたアセンブリを直接参照できます。 また、アセンブリがサポートされている名前空間のクラスのみを使用する場合、すべてが正常に機能します。 未実現のクラスにアクセスしようとすると、NotImplementedExceptionが発生します。 これは、Monotouchコンパイラのホワイトマジックです。
ただし、Windows Phone 7のプロジェクトでは、同様のコレクションへのリンクを追加することはできません(これは非常に論理的です)。 「しかし、Portable Class Libraryはどうですか?..」-あなたは尋ねます。 これがブラックマジックの始まりです。Mono*プロジェクトでPCLまたはWP7用にコンパイルされたアセンブリを使用しようとすると、エラーメッセージが表示されます。WP7またはPCLのライブラリを参照するアセンブリをロードすることはできません。
これがなぜこのように実装されているのか、私にはまだわかりません。 このテクニカルサポートに関するすべての質問への回答:「近日公開」。 唯一の良いニュースは、少し前にMonoDevelop(Mac上のMonotouchの開発環境)の新しいバージョンがリリースされたことであり、その説明は部分的なPCLサポートが提供されていることを明確に示していましたが、どこで正確に理解できませんでした。
実装
そのため、関心のあるすべてのプラットフォームで必要なライブラリを実装しているため、必要なクラスを使用するすべてのプラットフォームに対して1つのアセンブリを作成することはできません。 Windowsプラットフォーム用とMonoプラットフォーム用の2つのアセンブリをコンパイルする必要があります。
しかし、ここでも小さな問題に直面しています。 Webサービスのクライアントを実装するときに最も便利なクラスはWebClientです。 しかし、いくつかの不可解な理由により、Windows Phone 7およびデスクトップアプリケーションに実装されていますが、PCLの第2版から削除されました。 開発者は、WebClientがMetroアプリケーションでサポートされていないという事実でこれを主張しています。 したがって、Metroを含むアプリケーションを開発する場合は、下位レベルのクラスWebHttpRequestおよびWebHttpResponseを使用する必要があります。 簡単にするために、WebClientを操作するためのプロキシクラスを実装する例を示します。
必要なもの:
- Visual Studio 2010 SP 1;
- Visual Studio 2010用のWindows Phone SDK。
- Visual Studio 2010のMonodroid。
- Mac上のMonoDevelop 3.0.2。
- Newtonsoft.Json。
仕事に取り掛かる。
1. Windows Phone SDKとMonodroidをインストールします。 2つのプロジェクトを作成します。最初のプロジェクトはWindows Phoneライブラリで、2番目のプロジェクトはAndroidクラスライブラリです。 ユニバーサルWindowsライブラリを開発する場合は、Windows Phoneクラスライブラリの代わりにポータブルクラスライブラリを作成します。 ただし、この場合、Webサービスを操作するには、同じあまり便利ではないHttpWebRequestとHttpWebResponseを使用する必要があります。
2.次に、Androidクラスライブラリを使用して主な作業を行います。 このアセンブリとMonotouchプロジェクトとの互換性を確保するには、このアセンブリにMonodroid固有の追加リンクがないことを確認する必要があります。 プロジェクトでは、次のリンクを残します。
- システム
- System.Net;
- Newtonsoft.Json(JSONデシリアライゼーション用のライブラリ)。
3. http:// webservice:47154 / rest / vendorにあり、ソフトウェアメーカーのリストを返す、ある種の球状のRESTサービスが真空内にあるとします。
このサービスを使用するには、次のコードを記述するだけで十分です(Webサービスの応答が逆シリアル化されるクラスと、サービスが要求するプロキシクラス自体を作成します)。
// public class Vendor { public int Id { get; set; } public string Name { get; set; } public string Description { get; set; } } // - - public class VendorsProxy { private string _host; public VendorsProxy(string host) { _host = host; } public event VendorsEventHandler GetVendorsCompleted; public void GetVendors() { var client = new WebClient(); client.DownloadStringCompleted += (s, e) => { var vendors = JsonConvert.DeserializeObject<IEnumerable<Vendor>>(e.Result); if (GetVendorsCompleted != null) GetVendorsCompleted(new VendorsEventArgs(vendors)); }; client.DownloadStringAsync(new Uri(_host + @"rest/vendor")); } } public delegate void VendorsEventHandler(VendorsEventArgs vendors); public class VendorsEventArgs : EventArgs { public IEnumerable<Vendor> Vendors { get; private set; } public VendorsEventArgs(IEnumerable<Vendor> vendors) { Vendors = vendors; } }
4.これで、WPライブラリプロジェクトに、ファイル自体ではなく、Androidクラスライブラリプロジェクトのファイルへのリンクを追加するだけで十分です。
実際、それがすべてです。 ソリューションを完全にアセンブルすると、出力は2つのアセンブリになり、Windows PhoneとiOSおよびAndroidを搭載したデバイスの両方で同等に機能します。 次のように、任意のプラットフォームでWebサービスを使用できます。
var proxy = new VendorsProxy("http://mywebservice:8080/"); proxy.GetVendorsCompleted += (vendors) => { BindVedorsToVoewModel(vendors.Vendors); }; proxy.GetVendors();
疑い
もちろん、そのような普遍性を達成するために、そのような「タンバリンとのダンス」の必要性について議論することができます。確かに、各プラットフォームには独自の仕様と独自の最適な作業方法があります。 ただし、自信を持って.NETプログラマーであり、Webサービスで動作するシンプルなモバイルアプリケーションをすばやく作成する必要がある場合、このソリューションは役立ちます。
Habrasocietyがこのトピックに興味がある場合は、次の記事で、クロスプラットフォームアプリケーションで接続を保護する方法について説明します。
Positive Technologies、シニアプログラマー、Sergey Shulikによる投稿。