rksoftware

Visual Studio とか C# とかが好きです

城東.NET #35 勉強会を開催しました。

■ 城東.NET

城東.NET #35 を開催しました。

城東.NET は東京の最近は秋葉原で毎月第3水曜日に開催している .NET 系の勉強会です。
発表を中心として、発表でなくとも最近やった事や新しい情報などを参加者で共有している会です。

私は Android バインド ライブラリ というタイトルで話をしました。

最近、Android バインド ライブラリを触り始めててこずっているみ話です。

■ 次回予定

来月は 09月21日(水)に開催の予定です。

.NET に関心のある方、是非遊びに来てください。

Xamarin.Android で ARCore Sceneform (目次)

先日、Android のサンプルコードを Xamarin.Android に書き換えてみた記事を書きました。

その際に長い戦いとなった Android バインド ライブラリ 作成について書いていきます。
全くの事前学習無しからの挑戦で色々やらかしながらなんとか動作するところまで長い旅路でした。今回はその目次です。

なるべく色々嵌るように一気に作らず少しづつ作ってみました。実際には初手で一気に複数のライブラリを作ってしまうのが良いと思います。

Android バインド ライブラリ を作る

Xamarin Android で ARCore Sceneform (プロジェクト作成)

Xamarin.Android で ARCore Sceneform (基本)

Xamarin.Android で ARCore Sceneform (2つ目以降のエラーを順に対応 その1)

Xamarin.Android で ARCore Sceneform (2つ目以降のエラーを順に対応 その2)

Xamarin.Android で ARCore Sceneform (2つ目以降のエラーを順に対応 その3)

Xamarin.Android で ARCore Sceneform (2つ目以降のエラーを順に対応 その3)

先日、Android のサンプルコードを Xamarin.Android に書き換えてみた記事を書きました。

その際に長い戦いとなった Android バインド ライブラリ 作成について書いていきます。 今回は、6歩目 - エラーに順に対応していく更に続きです。

目次はこちら ↓

■ 前回のおさらい

前回の記事です。

少しづつエラーを解消して行っています。

■ エラー CS0234 型または名前空間の名前 'Rendering' が名前空間 'Com.Google.AR.Sceneform' に存在しません (アセンブリ参照があることを確認してください)

これは単純にライブラリの参照設定が不足しています。
https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/ux/sceneform-ux/1.9.0/sceneform-ux-1.9.0.aar
のプロジェクトから
https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/rendering/1.9.0/rendering-1.9.0.aar
のプロジェクトを参照します。

■ エラー java/lang/String;Ljava/util/concurrent/CompletableFuture;Ljava/lang/String;)Ljava/util/concurrent/CompletableFuture; : invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13)

■ エラー com.android.dx.cf.code.SimException: ERROR in com.google.ar.sceneform.rendering.CameraStream.:(ILcom/google/ar/sceneform/rendering/Renderer;)V: invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13)

Android アプリ プロジェクトのプロパティで Android オプションDex コンパイラd8 を選択。

ビルドエラーがなくなりました

おめでとうございます! ありがとうございます! ここでビルドエラーがなくなりました!

満を持して実行すると、なんと! 実行時エラーです。

■ Unhandled Exception: Android.Views.InflateException: が発生しました

SetContentView(Resource.Layout.activity_main); でエラーが発生します。エラーを深堀してみると

{Android.Views.InflateException: Binary XML file line #15: Binary XML file line #15: Binary XML file line #15: Error inflating class com.google.ar.sceneform.ArSceneView ---> Android.Views.InflateException: Binary XML file line #15: Binary XML file line #15: Error inflating class com.google.ar.sceneform.ArSceneView ---> Android.Views.InflateException: Binary XML file line #15: Error inflating class com.google.ar.sceneform.ArSceneView ---> Java.Lang.Reflect.InvocationTargetException: Exception of type 'Java.Lang.Reflect.InvocationTargetException' was thrown. ---> Java.Lang.NoClassDefFoundError: Failed resolution of: Lcom/google/android/filament/android/UiHelper$RendererCallback; ---> Java.Lang.ClassNotFoundException: Didn't find class "com.google.android.filament.android.UiHelper$RendererCallback"

根っこは

Java.Lang.ClassNotFoundException:
Didn't find class "com.google.android.filament.android.UiHelper$RendererCallback"

です。

見つからないクラスの含まれるライブラリで バインド ライブラリ を作って Android アプリ プロジェクトから参照します。
https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/filament-android/1.9.0/filament-android-1.9.0.aar

そして、実行。今度こそ、、、実行時エラー!

Unhandled Exception:
Java.Lang.NoSuchMethodError: <Timeout exceeded getting exception details>

■ Unhandled Exception: Java.Lang.NoSuchMethodError:

このエラーはいくつかのパターンで出ますが、今回はライブラリのバージョンの不整合でした。
今回の手順では各 .aar ファイルのバージョンが 1.9.0でした。バインド ライブラリの作成で試行錯誤している間にライブラリがバージョンアップしていて、NuGet パッケージ Xamarin.Google.ARCore も最新が 1.11.0 になっていました。
今回は Xamarin.Google.ARCore も 1.9.0 にしました。

■ 実行

これでようやく ARCore で遊ぶことができました。
f:id:rksoftware:20190811160427j:plain

Xamarin.Android で ARCore Sceneform (2つ目以降のエラーを順に対応 その2)

先日、Android のサンプルコードを Xamarin.Android に書き換えてみた記事を書きました。

その際に長い戦いとなった Android バインド ライブラリ 作成について書いていきます。 今回は、5歩目 - MainActivity.cs の2つ目以降のエラーに順に対応していく続きです。

目次はこちら ↓

■ 前回のおさらい

前回の記事です。

必要なライブラリを追加し、少しづつエラーを解消して行っています。

■ エラー CS0246 型または名前空間の名前 'AnchorNode' が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)

AnchorNode クラスは
https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/core/1.9.0/core-1.9.0.aar
のライブラリにいるはずですが、生成されていません。このクラスは
https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/sceneform-base/1.9.0/sceneform-base-1.9.0.aar
に依存するので、このライブラリで Android バインド ライブラリプロジェクトを作って参照します。

■ sceneform-base-1.9.0.aar プロジェクトのエラー

いくつかのエラーが出ます。

エラー    CS0534  'Box' は継承抽象メンバー 'CollisionShape.MakeCopy()' を実装しません。
エラー   CS0534  'Sphere' は継承抽象メンバー 'CollisionShape.MakeCopy()' を実装しません。
エラー   CS0535  'QuaternionEvaluator' はインターフェイス メンバー 'ITypeEvaluator.Evaluate(float, Object, Object)' を実装しません。
エラー   CS0535  'Vector3Evaluator' はインターフェイス メンバー 'ITypeEvaluator.Evaluate(float, Object, Object)' を実装しません。

今回も使わないので消してしまいます。

<remove-node path="/api/package[@name='com.google.ar.sceneform.collision']/class[@name='Box']" />
<remove-node path="/api/package[@name='com.google.ar.sceneform.collision']/class[@name='Sphere']" />
<remove-node path="/api/package[@name='com.google.ar.sceneform.math']/class[@name='QuaternionEvaluator']" />
<remove-node path="/api/package[@name='com.google.ar.sceneform.math']/class[@name='Vector3Evaluator']" />

■ エラー CS1729 'AnchorNode' には、引数 1 を指定するコンストラクターは含まれていません

AnchorNode の引数を一つとるコンストラクタの引数が別のライブラリのクラスのため生まれていません。
NuGet パッケージ Xamarin.Google.ARCore を追加します。

■ エラー CS0400 型名または名前空間名 'Google' がグローバル名前空間に見つかりませんでした (アセンブリ参照が存在することを確認してください)

https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/ux/sceneform-ux/1.9.0/sceneform-ux-1.9.0.aar
のプロジェクトに NuGet パッケージ Xamarin.Google.ARCore を追加します。

■ 大量のエラー

エラー    CS0534  'RotationController' は継承抽象メンバー 'BaseTransformationController.OnContinueTransformation(Object)' を実装しません。
エラー   CS0534  'RotationController' は継承抽象メンバー 'BaseTransformationController.CanStartTransformation(Object)' を実装しません。
エラー   CS0534  'RotationController' は継承抽象メンバー 'BaseTransformationController.OnEndTransformation(Object)' を実装しません。
エラー   CS0534  'ScaleController' は継承抽象メンバー 'BaseTransformationController.CanStartTransformation(Object)' を実装しません。
エラー   CS0534  'ScaleController' は継承抽象メンバー 'BaseTransformationController.OnContinueTransformation(Object)' を実装しません。
エラー   CS0534  'ScaleController' は継承抽象メンバー 'BaseTransformationController.OnEndTransformation(Object)' を実装しません。
エラー   CS0534  'TranslationController' は継承抽象メンバー 'BaseTransformationController.OnContinueTransformation(Object)' を実装しません。
エラー   CS0534  'TranslationController' は継承抽象メンバー 'BaseTransformationController.CanStartTransformation(Object)' を実装しません。
エラー   CS0534  'TranslationController' は継承抽象メンバー 'BaseTransformationController.OnEndTransformation(Object)' を実装しません。

消します。

<remove-node path="/api/package[@name='com.google.ar.sceneform.ux']/class[@name='RotationController']" />
<remove-node path="/api/package[@name='com.google.ar.sceneform.ux']/class[@name='ScaleController']" />
<remove-node path="/api/package[@name='com.google.ar.sceneform.ux']/class[@name='TranslationController']" />

■ エラー CS0012 型 'RayHit' は、参照されていないアセンブリに定義されています。アセンブリ 'XXXXXXXX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' に参照を追加する必要があります

メッセージに従い
https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/ux/sceneform-ux/1.9.0/sceneform-ux-1.9.0.aar
のプロジェクトで
https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/sceneform-base/1.9.0/sceneform-base-1.9.0.aar
のプロジェクトを参照します。

■ エラー CS1061 'TransformableNode' に 'Renderable' の定義が含まれておらず、型 'TransformableNode' の最初の引数を受け付けるアクセス可能な拡張メソッド 'Renderable' が見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足していないことを確認してください。

setRenderable メソッドは TransformableNode のスーパークラスである
https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/core/1.9.0/core-1.9.0.aar
内のクラスのメソッドですが、引数の型は
https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/rendering/1.9.0/rendering-1.9.0.aar
内のクラスです。

https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/core/1.9.0/core-1.9.0.aar
のプロジェクトで https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/rendering/1.9.0/rendering-1.9.0.aar
のプロジェクトを参照します。

■ 最大のエラー

ここで、最も難易度の高いエラーが発生します。

エラー        繧ィ繝ゥ繝シ: Light縺ョLightChangedListener縺ッpublic縺ァ縺ッ縺ゅj縺セ縺帙s縲ゅヱ繝・こ繝シ繧ク螟悶°繧峨・繧「繧ッ繧サ繧ケ縺ァ縺阪∪縺帙s
        com.google.ar.sceneform.rendering.Light.LightChangedListener
豕ィ諢・荳驛ィ縺ョ蜈・蜉帙ヵ繧。繧、繝ォ縺ッ髱樊耳螂ィ縺ョAPI繧剃スソ逕ィ縺セ縺溘・繧ェ繝シ繝舌・繝ゥ繧、繝峨@縺ヲ縺・∪縺吶・
豕ィ諢・隧ウ邏ー縺ッ縲・Xlint:deprecation繧ェ繝励す繝ァ繝ウ繧呈欠螳壹@縺ヲ蜀阪さ繝ウ繝代う繝ォ縺励※縺上□縺輔>縲・
豕ィ諢・蜈・蜉帙ヵ繧。繧、繝ォ縺ョ謫堺ス懊・縺・■縲∵悴繝√ぉ繝・け縺セ縺溘・螳牙・縺ァ縺ッ縺ェ縺・b縺ョ縺後≠繧翫∪縺吶・
豕ィ諢・隧ウ邏ー縺ッ縲・Xlint:unchecked繧ェ繝励す繝ァ繝ウ繧呈欠螳壹@縺ヲ蜀阪さ繝ウ繝代う繝ォ縺励※縺上□縺輔>縲・

一目見てわかるでしょう。何のエラーかわからない、と。
消します。慈悲はありません。
https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/rendering/1.9.0/rendering-1.9.0.aar
のプロジェクトです。

<remove-node path="/api/package[@name='com.google.ar.sceneform.rendering']/interface[@name='Light.LightChangedListener']"/>

まだまだエラーは消えないので、続きも書いて行こうと思います。

(つづく)

Xamarin.Android で ARCore Sceneform (2つ目以降のエラーを順に対応 その1)

先日、Android のサンプルコードを Xamarin.Android に書き換えてみた記事を書きました。

その際に長い戦いとなった Android バインド ライブラリ 作成について書いていきます。 今回は、4歩目 - MainActivity.cs の2つ目以降のエラーに順に対応して行きます。

目次はこちら ↓

■ 前回のおさらい

前回の記事です。

1つ目のクラスはエラーを解消できました。

■ com.google.ar.sceneform.rendering.ModelRenderable クラス

このクラスは、
https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/rendering/1.9.0/rendering-1.9.0.aar
にいます。これまでと同様の手順で Android バインド ライブラリプロジェクトを作成します。

■ エラー

いくつかエラーが出るので、頑張っていきます。

エラー    CS0534  'ModelRenderable' は継承抽象メンバー 'Renderable.MakeCopy()' を実装しません。
エラー   CS0111  型 'ModelRenderable.Builder' は、'MakeRenderable' と呼ばれるメンバーを同じパラメーターの型で既に定義しています。
エラー   CS0111  型 'ModelRenderable.Builder' は、'Build' と呼ばれるメンバーを同じパラメーターの型で既に定義しています。
エラー   CS0513  'ModelRenderable.Builder.GetRenderableClass()' は抽象ですが、非抽象クラスの 'ModelRenderable.Builder' に含まれています。
エラー   CS0534  'ViewRenderable' は継承抽象メンバー 'Renderable.MakeCopy()' を実装しません。
エラー   CS0111  型 'ViewRenderable.Builder' は、'MakeRenderable' と呼ばれるメンバーを同じパラメーターの型で既に定義しています。
エラー   CS0111  型 'ViewRenderable.Builder' は、'Build' と呼ばれるメンバーを同じパラメーターの型で既に定義しています。
エラー   CS0513  'ViewRenderable.Builder.GetRenderableClass()' は抽象ですが、非抽象クラスの 'ViewRenderable.Builder' に含まれています。

'XXXXXXXX' は継承抽象メンバー 'Renderable.MakeCopy()' を実装しません

スーパークラス Renderable の MakeCopy() メソッドは次の様になっています。

public abstract global::Com.Google.AR.Sceneform.Rendering.Renderable MakeCopy ();

エラーの出ているクラス(例えば ModelRenderable クラス)では、

public virtual unsafe global::Com.Google.AR.Sceneform.Rendering.ModelRenderable MakeCopy ()

で戻りの型が違っています。サブクラス側の方をスーパークラスの型に変えてみました。

<attr path="/api/package[@name='com.google.ar.sceneform.rendering']/class[@name='ModelRenderable']/method[@name='makeCopy' and count(parameter)=0]"
      name="managedReturn">Com.Google.AR.Sceneform.Rendering.Renderable</attr>

型 'XXXXXXXX.Builder' は、'MakeRenderable' と呼ばれるメンバーを同じパラメーターの型で既に定義しています

エラーの出ているクラス(例えば ModelRenderable クラス)では、

protected unsafe global::Com.Google.AR.Sceneform.Rendering.ModelRenderable MakeRenderable () { /* 省略 */ }
protected unsafe global::Com.Google.AR.Sceneform.Rendering.Renderable MakeRenderable () { /* 省略 */ }

で戻り値違いの同名メソッドが作られています。今回、MakeRenderable メソッドは使わないので、削除してみました。

<remove-node path="/api/package[@name='com.google.ar.sceneform.rendering']/class[@name='ModelRenderable.Builder']/method[@name='makeRenderable' and count(parameter)=0]"/>

型 'XXXXXXXX' は、'Build' と呼ばれるメンバーを同じパラメーターの型で既に定義しています

'XXXXXXXX.Builder.GetRenderableClass()' は抽象ですが、非抽象クラスの 'XXXXXXXX.Builder' に含まれています

やはり消してみました。

<remove-node path="/api/package[@name='com.google.ar.sceneform.rendering']/class[@name='ModelRenderable.Builder']/method[@name='build' and count(parameter)=0]"/>
<remove-node path="/api/package[@name='com.google.ar.sceneform.rendering']/class[@name='ModelRenderable.Builder']/method[@name='getRenderableClass' and count(parameter)=0]"/>

■ 追加エラー

エラーには一通り対処しましたが追加のエラーがでるので、頑張っていきます。

エラー    CS0513  'ModelRenderable.Builder.RenderableClass.get' は抽象ですが、非抽象クラスの 'ModelRenderable.Builder' に含まれています。
エラー   CS0513  'ViewRenderable.Builder.RenderableClass.get' は抽象ですが、非抽象クラスの 'ViewRenderable.Builder' に含まれています。

'XXXXXXXX.Builder.RenderableClass.get' は抽象ですが、非抽象クラスの 'XXXXXXXX.Builder' に含まれています。

今回は、抽象メンバーが非抽象クラスいるのが悪いと言われているので、試しに該当クラスを抽象クラスにしてみました。

<attr path="/api/package[@name='com.google.ar.sceneform.rendering']/class[@name='ModelRenderable.Builder']"
      name="abstract">true</attr>
<attr path="/api/package[@name='com.google.ar.sceneform.rendering']/class[@name='ModelRenderable.Builder']"
      name="final">false</attr>

■ 追加エラー

ここまでのエラーには一通り対処しましたが追加のエラーがでるので、頑張っていきます。

エラー    CS0102  型 'ModelRenderable.Builder' は既に 'cb_getSelf' の定義を含んでいます。
エラー   CS0111  型 'ModelRenderable.Builder' は、'GetGetSelfHandler' と呼ばれるメンバーを同じパラメーターの型で既に定義しています。
エラー   CS0111  型 'ModelRenderable.Builder' は、'n_GetSelf' と呼ばれるメンバーを同じパラメーターの型で既に定義しています。
エラー   CS0102  型 'ViewRenderable.Builder' は既に 'cb_getSelf' の定義を含んでいます。
エラー   CS0111  型 'ViewRenderable.Builder' は、'GetGetSelfHandler' と呼ばれるメンバーを同じパラメーターの型で既に定義しています。
エラー   CS0111  型 'ViewRenderable.Builder' は、'n_GetSelf' と呼ばれるメンバーを同じパラメーターの型で既に定義しています。
エラー   CS0229  ModelRenderable.Builder.cb_getSelf' と 'ModelRenderable.Builder.cb_getSelf' 間があいまいです
エラー   CS0229  ModelRenderable.Builder.cb_getSelf' と 'ModelRenderable.Builder.cb_getSelf' 間があいまいです
エラー   CS0121  次のメソッドまたはプロパティ間で呼び出しが不適切です: 'ModelRenderable.Builder.n_GetSelf(IntPtr, IntPtr)' と 'ModelRenderable.Builder.n_GetSelf(IntPtr, IntPtr)'
エラー   CS0229  ModelRenderable.Builder.cb_getSelf' と 'ModelRenderable.Builder.cb_getSelf' 間があいまいです
エラー   CS0229  ModelRenderable.Builder.cb_getSelf' と 'ModelRenderable.Builder.cb_getSelf' 間があいまいです
エラー   CS0229  ModelRenderable.Builder.cb_getSelf' と 'ModelRenderable.Builder.cb_getSelf' 間があいまいです
エラー   CS0121  次のメソッドまたはプロパティ間で呼び出しが不適切です: 'ModelRenderable.Builder.n_GetSelf(IntPtr, IntPtr)' と 'ModelRenderable.Builder.n_GetSelf(IntPtr, IntPtr)'
エラー   CS0229  ModelRenderable.Builder.cb_getSelf' と 'ModelRenderable.Builder.cb_getSelf' 間があいまいです

各エラー

どれも getSelf メソッドのようなので消してみます。

<remove-node path="/api/package[@name='com.google.ar.sceneform.rendering']/class[@name='ModelRenderable.Builder']/method[@name='getSelf' and count(parameter)=0]"/>

ここまでで、いったん Android バインド ライブラリがビルドできたので、MainActivity.cs のエラー対処を進めて行きます。

■ com.google.ar.core.HitResult クラス

このクラスは、NuGet パッケージ Xamarin.Google.ARCore を追加します。

■ エラー CS0117 'Resource.Id' に 'ux_fragment' の定義がありません

\Resources\layout\activity_main.axml の中身を Android サンプルのレイアウトの xml 中身で上書きします。

■ エラー CS0117 'ModelRenderable' に 'CreateBuilder' の定義がありません

ModelRenderable のインナークラス Builder と builder() メソッドがかぶってしまっているのでメソッド名前を変えてみました。

<attr path="/api/package[@name='com.google.ar.sceneform.rendering']/class[@name='ModelRenderable']/method[@name='builder' and count(parameter)=0]"
      name="managedName">CreateBuilder</attr>

■ エラー CS1061 'ModelRenderable.Builder' に 'SetSource' の定義が含まれておらず、型 'ModelRenderable.Builder' の最初の引数を受け付けるアクセス可能な拡張メソッド 'SetSource' が見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足していないことを確認してください

SetSource メソッドは本来 ModelRenderable.Builder クラスのスーパークラスである Renderable.Builder クラスのメソッドですが、生成された C# コードでは継承関係がなくなっていました。
ModelRenderable.Builder クラスに SetSource メソッドを追加してみました。

<attr path="/api/package[@name='com.google.ar.sceneform.rendering']/class[@name='Renderable.Builder']/method[@name='setSource' and count(parameter)=2 and parameter[1][@type='android.content.Context'] and parameter[2][@type='int']]"
      name="return">com.google.ar.sceneform.rendering.Renderable.Builder</attr>

■ エラー CS0117 'Resource.Raw' に 'andy' の定義がありません

\Resources\ ディレクトリに raw ディレクトリを作ってその中に、 Android サンプルをビルドするとできる andy.sfb をコピーします。
プロパティでビルド アクションは AndroidResource にします。

まだまだエラーは消えないので、続きも書いて行こうと思います。

(つづく)

都道府県ごとの勉強会イベント数メモ

話のネタに使おうか思って connpass で公開されているイベント数を都道府県ごとに数えてみたメモです。

多い月少ない月あると思うので 2018 年の一年間 (2018/01/01 - 2018/12/31) を数えています。

順位 都道府県 件数
1 東京都 13,240
2 大阪府 1,784
3 愛知県 824
4 福岡県 777
5 神奈川県 535
6 北海道 377
7 京都府 290
8 沖縄県 254
9 広島県 224
10 埼玉県 208
11 宮城県 190
12 岡山県 176
13 兵庫県 167
14 長野県 159
15 千葉県 117
16 静岡県 117
17 熊本県 114
18 新潟県 88
19 島根県 85
20 山形県 74
21 茨城県 73
22 石川県 68
23 岩手県 66
24 鹿児島県 61
25 福島県 54
26 長崎県 52
27 三重県 48
28 栃木県 45
29 香川県 45
30 大分県 44
31 愛媛県 35
32 滋賀県 33
33 徳島県 33
34 富山県 30
35 群馬県 29
36 山口県 27
37 山梨県 24
38 奈良県 23
39 鳥取県 23
40 岐阜県 22
41 和歌山県 19
42 高知県 14
43 宮崎県 13
44 青森県 11
45 福井県 10
46 佐賀県 2
47 秋田県 1

Xamarin.Android で ARCore Sceneform (基本)

先日、Android のサンプルコードを Xamarin.Android に書き換えてみた記事を書きました。

その際に長い戦いとなった Android バインド ライブラリ 作成について書いていきます。 今回は、3歩目 - バインドライブラリのビルドエラーを解消するところまでです。

目次はこちら ↓

■ 必要なもの

今回の手順に必要なものは、

  • Android Studio
  • Xamarin の開発環境(この記事では Windows 環境でやってます)

です。Android Studio は書き換える前の Android 用コードの確認に使います。

■ 前回のおさらい

前回の記事です。

Android バインド ライブラリプロジェクトでビルドエラーになっていました。

f:id:rksoftware:20190815212113j:plain

■ エラー発生しているソースコードの確認

エラーとなっているのは C# のソースコードです。これは自動生成されたコードで、Visual Studio のエラー一覧でダブルクリックすれば開く(こともあります)。

f:id:rksoftware:20190818132525j:plain

開かない場合は .cs ファイルは \obj\Debug\generated\src にいるので直接開いて確認しました。

■ エラーの確認

今回については実は、C# ソースコードの確認は必要ありません。エラー一覧のメッセージと発生しているクラスから対処ができます。

エラー CS0534 'DragGesture' は継承抽象メンバー 'BaseGesture.RawSelf.get' を実装しません。

エラー CS0534 'PinchGesture' は継承抽象メンバー 'BaseGesture.RawSelf.get' を実装しません。

エラー CS0534 'TwistGesture' は継承抽象メンバー 'BaseGesture.RawSelf.get' を実装しません。

エラーの発生しているクラスは、Android アプリプロジェクトの MainActivity.cs で使用していないクラスです。なので、消してしまうことで対処が可能です。生成される C# ソースコードの調整は、前回も触れましたが Transforms\Metadata.xml で行います。
ここにどう書けばいいかは、次のページを参照。

そのほか、生まれるものの定義が \obj\Debug\api.xml に作られるのでこちらも参考になります。

<api>
  <package name="com.google.ar.sceneform.ux" jni-name="com/google/ar/sceneform/ux">
    <class abstract="false" deprecated="not deprecated" extends="java.lang.Object" extends-generic-aware="java.lang.Object" jni-extends="Ljava/lang/Object;" final="false" name="BaseArFragment.2" static="false" visibility="" jni-signature="Lcom/google/ar/sceneform/ux/BaseArFragment$2;">
      <implements name="android.content.DialogInterface.OnDismissListener" name-generic-aware="android.content.DialogInterface.OnDismissListener" jni-type="Landroid/content/DialogInterface$OnDismissListener;">
      </implements>
      <method abstract="false" deprecated="not deprecated" final="false" name="onDismiss" jni-signature="(Landroid/content/DialogInterface;)V" bridge="false" native="false" return="void" jni-return="V" static="false" synchronized="false" synthetic="false" visibility="public">
        <parameter name="arg0" type="android.content.DialogInterface" jni-type="Landroid/content/DialogInterface;">
        </parameter>
      </method>
    </class>

今回は、クラスを消してしまえば良いので Transforms\Metadata.xml は次のようにしました。

<metadata>
  <remove-node path="/api/package[@name='com.google.ar.sceneform.ux']/class[@name='DragGesture']" />
  <remove-node path="/api/package[@name='com.google.ar.sceneform.ux']/class[@name='TwistGesture']" />
  <remove-node path="/api/package[@name='com.google.ar.sceneform.ux']/class[@name='PinchGesture']" />
</metadata>

今回の様にとりあえず消してしまうのが一番手っ取り早く間違いがないです。
(実際には、消せない部分がエラーになって苦しみます)

これで、一旦エラーが消えるはずです。

はずです。(大抵消えません)

消えないときはプロジェクトを一度アンロードしてから再読み込みします。

■ 必要なクラスが生まれていない

Android バインド ライブラリプロジェクトのエラーは消えました。
ここで Android アプリのプロジェクトにプロジェクトに戻ってみると、欲しかったクラスが生成されていません(今回欲しかったクラスは com.google.ar.sceneform.ux.ArFragment)。Android Studio で確認してみると継承の根っこに android.support.v4.app.Fragment クラス、com.google.ar.sceneform.Scene がいます。

これらのクラスを手に入れるために、

  • android.support.v4.app.Fragment は NuGet Xamarin.Android.Support.Fragment を追加
  • com.google.ar.sceneform.Scene は、com/google/ar/sceneform/core/1.9.0/core-1.9.0.aar でもう一つ Android 場隠語ライブラリプロジェクトを作成

します。
core-1.9.0.aar は次からダウンロードしました。

https://dl.google.com/dl/android/maven2/com/google/ar/sceneform/core/1.9.0/core-1.9.0.aar

■ Android バインド ライブラリプロジェクトをもう一個作る

作り方は、最初の一つと同様です。プロジェクトを作ったら、これまで触ってきた Android バインド ライブラリプロジェクトから参照します。

f:id:rksoftware:20190818132805j:plain

参照を追加したらビルドを実行し、ライブラリプロジェクトをアンロード → 再読み込みします。
これで欲しかった Com.Google.AR.Sceneform.UX .ArFragment クラスが手にはいります。

**MainActivity.cs``` に名前空間の usig を追加します。

おめでとうございます! ありがとうございます!
無事、クラスが生まれてエラーが消えました。

後は基本的にこの繰り返しです。必要な Android バインド ライブラリを作って、\obj\Debug\generated\src のファイルを確認しながら Transforms\Metadata.xml を編集してを繰り返します。それで頑張ればゴールにたどり着きます。

f:id:rksoftware:20190811160427j:plain

概要は以上です。
ただし、この後でも様々な乗り越える壁があるので、続きも書いて行こうと思います。

(つづく)