How Xamarin.Android works
@atsushieno / atsushi xamarin.com
Agenda
How Xamarin.Android works
XAのアプリケーションモデル
.NETコードが動く仕組み
XAアプリケーションのbootstrap
YAPF寄りだけど今回はナシ
Java/Mono interopの詳細
dalvikとmonoのGC協調
IDEでAndroid開発をサポートするやり方
Xamarin
C#/.NET on iOS and Android
C#でnative APIを使ったアプリケーションを作れる
Visual Studio / Xamarin Studio IDE
Mono Projectの開発元
Mono
.NET on Linux, Mac, Windows etc.
CランタイムとC#コンパイラ/ライブラリの自前実装
GTK# (gtk+ & P/Invoke)
MonoDevelop IDE (GTK#で開発)
Cの組み込みAPI
(.NET組み込み環境: Silverlightプラグインなど)
Android
Android SDK: Java APIとビルドツール
Android NDK: gcc toolchainとCライブラリ
NativeActivity
LLVM/Clangもアリ
(IDE側: ADT, Android Studio)
NativeActivity...?
"NativeActivity allows you to write a completely native activity" "It is possible to write a completely native application"
"You should still create your project with Eclipse or <snip>"
WTF
Javaと変わらんやん…
Mono runtime on Android
monoランタイムはNDKでビルド可能
完全にCコード(たしか) / libcのみ依存->bionic
monoのARM JITが普通に動作可能
⇔iOS (JIT不可→AOT=事前コンパイルで対処)
(androidmono: コミュニティによる最初のandroid port)
Xamarin.Android
Mono.Android.dll: Android SDK API in C#
public class MyActivity : Android.App.Activity { ... }
XAはJava APIとJavaのフレームワークが前提
NativeActivity not supported.
C#コードはCILとしてmonoランタイム上で動作
Javaコードはdexとしてdalvik上で動作
(C#からdexに変換したりはしない)
Java Interop: from Mono to Java
Mono.Android APIがJNIをP/Invokeで呼び出す
libmonodroid: Cライブラリ(公開APIはナシ)
Android.Runtime.JNIEnvクラス
CのJNIEnv API相当
Java Interop: from Java to Mono
AndroidはよくJavaオブジェクトを生成・操作する
Android Callable Wrappers (ACW)
.NETベースのAndroidオブジェクトの型に
それぞれ対応するJavaコードが生成される
そのJava型がlibmonodroidをJNIで呼び出す
ACW
@Override
protected void onCreate(....)
{
n_onCreate(....);
}
native void n_onCreate(....); // invoked CIL
more ACW
static {
__md_methods =
"n_onCreate:(Landroid/os/Bundle;)V:�GetOnCreate_Landroid_os_Bundle_Handler\n" + "";
mono.android.Runtime.register(
"Some.MangedClass, Some.Assembly, ...", SomeJava.class, __md_methods);
}
(actually "ManagedClass" should be identical to "SomeJava")
Xamarin.Androidのapk
アプリケーションのapk(全アプリ)
"Shared Runtime" apk
共通dllとそれをアプリに提供するService
mscorlib.dll, System*.dllなど
"Platform API" apk
API Level別のdllが含まれる
Mono.Android.dllなど
アプリケーションの実行モデル
1) Shared Runtimeを利用 - デバッグビルド
1a) Embed: 普通のデプロイメント
毎回apkをインストール
apkに「共通のdll」は含まれない
1b) FastDev: 高速デプロイメント
apk中にdllはない(!) 1回だけインストール
アプリケーション空間にdllをコピーしてロード
更新が必要なファイルのみコピー
2) Bundle: 全部パッケージ - リリースビルド
アプリケーション実行モデル一覧
モデル | FastDev | Embed | Bundle |
想定用途l | 高速デバッグ | 遅いデバッグ? | リリース |
依存関係 | shared runtime | shared runtime | なし(単独配布可能) |
apk �deployment | 一度だけ | 毎回 | 毎回 |
apkサイズ | 非常に小さい | 大きい | 小さめ |
全コード量 | 多い | 多い | 削られる |
XAアプリケーションのbootstrap
[再掲] XA appは普通のJava app
全てのAndroid appは同じ流れで起動する
アプリケーションプロセスはZygoteからfork
どのアプリにもActivityThreadが割り当てられる
monoが初期化されないとCILコードは機能しない
でも初期化プロセスはJavaの世界
XAのbootstrapはAndroidManifest.xmlから見える
AndroidManifest.xml
<application
~:name="mono.android.app.Application" ...>
<provider
~:name="mono.MonoRuntimeProvider" .../>
<receiver
~:name="mono.android.Seppuku">
XA bootstrap components
mono.android.app.Application: これはダミー(!)
mono.MonoRuntimeProvider
monoランタイムを初期化して、(処理モデルに
よってはshared runtimeからdllを取り込んで)
アプリケーションに含まれるdllをロードする
mono.android.Seppuku: デバッガの切断を受理
アプリケーションのbootstrap詳細
Zygoteがプロセススレッドをfork
ActivityManagerがActivityThreadをアプリにbind
ActivityThread#bindApplication()
Providerのリストが生成されて http://goo.gl/OBhLY
それがこのメソッドに渡る http://goo.gl/LZLlk
ActivityThread#handleBindApplication()
Instrumentationが生成される(既定/独自)
installContentProviders(app, providers);
mInstrumentation#callApplicationOnCreate(app);
-> この順序ならカスタムApplicationクラスも安全に初期化
ただし…
ApplicationとProviderの初期化順は最近の動作
Application.onCreate()が先の場合も…
カスタムInstrumentationの初期化で問題
→これらに対応するACWでも初期化処理を追加
まとめ
Mono.AndroidはAndroidフレームワーク準拠
.NETコードはmonoランタイムで動作
Android API とのinterop
ACWがJNI経由で.NETオブジェクトを操作
JNI関数をP/InvokeしてJavaオブジェクトを操作
アプリケーションのbootstrap
ランタイムを適切なタイミングで初期化する
mono.MonoRuntimeProvider
参考文献
Anatomy-Physiology of an Android
https://sites.google.com/site/io/anatomy--physiology-of-an-android
Xamarin.Android: Architecture
http://docs.xamarin.com/guides/android/advanced_topics/architecture
DSAS開発者の部屋:Android アプリケーションが起動するまでの流れ
http://dsas.blog.klab.org/archives/52003951.html