アプリ自体はWebアプリだけれど、ネイティブアプリの中にWebViewを突っ込んでそのWebアプリを表示(つまりネィティブアプリの中にはViewもLogicもほとんどない)して配布自体はネィティブアプリというものをハイブリッドアプリと称するそうです。
このアプリの利点はちゃんと調べていませんが、Webアプリに対してWebViewを通していろいろ操作で来たり、ブラウザで表示していて戻るボタンとかURL欄をどうにかしたいとかブラウザの外観にしたくなかったりとか、ブックマークしてもらうんじゃなくてアプリインストールしてアイコンをメニューに表示したいとかまあいろいろありそうです。
欠点としては当然WebViewの中で表示しているWebアプリが主体なので、まあ、Webアプリの制限は若干緩和されるけれど基本はWebアプリでできることしかできないと思うくらいが爾来踏まなくてよさそうな気がします。まあ、具体的な地雷がなんなのかまでは深追いしてませんが。
で、ちょっとXamarinで作ってみました。これだけでも大変でした。
ということで、Hallo Worldはやらずに
「はじめてのXamarinアプリ」
始まるよ!
私の周りだと「古いAndroidは特にサポートしなくていいじゃないかな?」的な雰囲気もあるので「Ice Cream Sandwich」なアプリとして作成します。このテンプレートを使うとAPIレベル15、Android 4.0.3に相当します。
初期状態のプロジェクト構成は次のような形になります。
Resources\Layoutの中に、いわゆるViewが入ります。形式はAXMLというやつでXAMLよりも正直しょぼいです。
Activity1.csが画面に対するコードビハインドを記述しているところになります。
なんとなくしっくりこないので、ちょっと名前を変えてみましょう。ついでに場所なんかも変えてみたりして。
なんとなく普通のC#アプリっぽくなりましたよね?
あと、設定しなくても動作しますが、プロジェクトのプロパティで[Android Manifest]の[Application name]あたりも設定しておきましょう。
それではMain.axmlに画面デザインをしてみましょう。テンプレートから作成された直後にはボタンが1つだけある画面になっています。
まずはボタンを削除してWebViewを張り付けてみましょう。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <WebView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/LocalWebView" /> </LinearLayout>
もちろんコントロールについてはプロパティウィンドウにプロパティが表示されます。
ただし、プロパティとメソッドが分かれていなくて1リストに両方混在しています。このあたりは改善して欲しいですね。
最後にコードビハインド側に表示するWebアプリのURLを設定してみましょう。ここが意外と情報が少ないのと、公式オンラインヘルプが分かりづらかった部分になります。
using Android.App; using Android.OS; using Android.Views; using Android.Webkit; namespace AndroidHybridSample { [Activity(Label = "AndroidHybridSample", MainLauncher = true, Icon = "@drawable/icon")] public class Main : Activity { protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); RequestWindowFeature(WindowFeatures.NoTitle); SetContentView(Resource.Layout.Main); WebView localWebView = FindViewById(Resource.Id.LocalWebView); localWebView.SetWebViewClient(new CustomWebViewClient()); localWebView.LoadUrl("http://hatsune.hatenablog.jp/"); localWebView.Settings.LoadWithOverviewMode = true; localWebView.Settings.UseWideViewPort = true; localWebView.Settings.JavaScriptEnabled = true; } private class CustomWebViewClient : WebViewClient { public override bool ShouldOverrideUrlLoading(WebView view, string url) { view.LoadUrl(url); return true; } } } }
実行してみよう
F5ではなくて[ctrl]+[shift]+[B]でビルドとエミュレータへのデプロイと実行が行われます。
Visual Studioとエミュレータ間でリモートデバッグが構成されているので、Visual Studio側でブレークポイントをはって動くを調査するようなことも可能です。
エミュレータで実行して迷った点/困った点
Xamarinのプロジェクトテンプレートですが、そのまま起動しようとするといくつかエラーがでるパターンがありました。
その時に表示されるダイアログと対処方法を調べてみました。
なぜか、APIレベル10のエミュレータが立ち上がるように設定される
Visual Studioのメニューにある起動するエミュレータのAPIレベル指定がなぜか「15」にしてたのに「10」に変わっているときが何回かありました。この状態で起動すると、APIレベル15でアプリを作成しているので次のようなエラーダイアログが表示されてエミュレータでアプリが起動しません。
対処方法としては、MonoForAndroid_API_15を選択してから保存して再度実行してみてください。
エミュレータが起動しない
デバイスがつながっていないかエミュレータが選択されていないと表示されますが、VSを再起動するとなおったりします。
エミュレータが遅いと表示される
これは起動時に必ず出てしまうそうなので気にしないのがベストアンサー。
エミュレータでの初回実行が遅い
ソースのビルドとか、アプリケーションをデバイスにインストールするのは早いのですが、そのあとに「shared runtime」のインストール、そして極めて時間がかかる「platform faramework」のインストールが影響しています。
一度実行してしまえば、次回以降は【そのプロジェクトについては】「shared runtime」「platform framework」のインストールはスキップされるのでかなり改善します。なお、このインストールはプロジェクト単位なので別のプロジェクトの初回実行はやっぱり時間がかかります。
パッケージに失敗する
過去に1度だけでて再現しないエラーがこのエラーです。たぶん、一度保存してVisual Studio再起動後に読み直して治ったと思います。
エミュレータで実行が始まったようだけれどどうすればいいかわからない
ロック画面になっていたら、丸付き鍵マークを右にスライドしてロックを解除します。
ロック画面のロックを解けば自動的にアプリが起動します。
ホーム画面だとしたら下真ん中にある「丸付き三段点々」をタップします。
それからアプリ一覧でアプリを探して実行しましょう。
アプリ名はプロジェクトプロパティの[Andoroid Manifest]-[Application Name]で変更できます。省略地はプロジェクト名です。
ここまでできたので、次はバージョン情報画面をネィティブ側でつくって表示するところをやってみようかな。