Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Xamarin.Android で始めるクロスプラットフォームモバイルアプリ開発 #d...
Search
amay077
March 09, 2017
Programming
3
3.7k
Xamarin.Android で始めるクロスプラットフォームモバイルアプリ開発 #droidkaigi #droidkaigi1
DroidKaigi2017 -
https://droidkaigi.github.io/2017/
day2 AM10:40-11:30 Room1 の発表資料です。
amay077
March 09, 2017
Tweet
Share
More Decks by amay077
See All by amay077
愛知県新型コロナ対策サイト(非公式)の紹介
amay077
0
330
愛知県コロナ対策サイトが立ち上がってから
amay077
0
120
Xamarin.Forms Hot Reload のススメ
amay077
0
900
クロスプラットフォームモバイルアプリ開発ツール総ざらい2019 〜Titanium Mobile から Kotlin/Native まで〜 #droidkaigi
amay077
11
10k
ハムスター検出器を1日で作ってみた #NGK2018B
amay077
1
1.1k
App Center から Azure Pipeline に乗り換えた話
amay077
0
1.4k
Xamarin.Forms.GoogleMaps について
amay077
0
1.5k
Xamarin.Android で始めるクロスプラットフォームモバイルアプリ開発 #jaghama
amay077
0
660
Xamarin.Android で始めるクロスプラットフォームモバイルアプリ開発 #jxug
amay077
0
990
Other Decks in Programming
See All in Programming
AI Schema Enrichment for your Oracle AI Database
thatjeffsmith
0
380
atmaCup #23でAIコーディングを活用した話
ml_bear
3
600
カスタマーサクセス業務を変革したヘルススコアの実現と学び
_hummer0724
0
850
ふん…おもしれぇ Parser。RubyKaigi 行ってやるぜ
aki_pin0
0
110
要求定義・仕様記述・設計・検証の手引き - 理論から学ぶ明確で統一された成果物定義
orgachem
PRO
1
360
Raku Raku Notion 20260128
hareyakayuruyaka
0
410
朝日新聞のデジタル版を支えるGoバックエンド ー価値ある情報をいち早く確実にお届けするために
junkiishida
1
190
Swift at Scale: Where Performance Really Comes From
kateinoigakukun
0
120
CSC307 Lecture 12
javiergs
PRO
0
440
JPUG勉強会 OSSデータベースの内部構造を理解しよう
oga5
2
200
Amazon Bedrockを活用したRAGの品質管理パイプライン構築
tosuri13
5
870
Head of Engineeringが現場で回した生産性向上施策 2025→2026
gessy0129
PRO
0
180
Featured
See All Featured
Measuring & Analyzing Core Web Vitals
bluesmoon
9
760
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Balancing Empowerment & Direction
lara
5
910
Imperfection Machines: The Place of Print at Facebook
scottboms
269
14k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
RailsConf 2023
tenderlove
30
1.4k
Practical Orchestrator
shlominoach
191
11k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
280
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
57
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
170
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.7k
Transcript
Xamarin.AndroidͰ࢝ΊΔ ΫϩεϓϥοτϑΥʔϜ ϞόΠϧΞϓϦ։ൃ 2017.3.10 DroidKaigi2017 @amay077
About me • Ԟࢁ ༟ਈ - @amay077ʢ͋Ί͍ʣ • ۀܥϓϩάϥϚ+α •
ѪݝࡏॅͷϑϧϦϞʔτϫʔΧʔ • ཧใγεςϜɺҐஔใϓϩάϥϛϯά • Android, iOS, Xamarin, Java, C#, Salesforce
Work for • B2B͚PaaSɺݿཧɾӡૹۀ͚SaaS • AWS, Elasticsearch, Cassandra, Lambda,
etc • શһ͕ϑϧϦϞʔτϫʔΧʔ ͓ࣄ༰ϦϞʔτͰͷಇ͖ํͳͲڵຯ͋Δํɺؾܰʹฉ͍͍ͯͩ͘͞
Target • Androidॳʙதڃऀ • iOSΞϓϦ։ൃͯ͠Δʗͦ͠͏ͳਓ • Xamarinͬͯฉ͍ͨ͜ͱ͋Δ͚Ͳ࣮ࡍԿͳͷʁ ͱࢥͬͯΔਓ • .NETܥͷ։ൃ͋·Γͨ͠ࣄ͕ͳ͍ਓ
Agenda 1. Xamarinͱʁ 2. ௨ৗͷAndroid։ൃͱͷҧ͍ 3. C#ͷར 4. X-PlatΞϓϦ։ൃͱίʔυͷڞ༗ 5.
Xamarinͷ͍Ͳ͜Ζ
Xamarinͱʁ ⏰ 45
Xamarinͱʁ /&5ϑϨʔϜϫʔΫʢ.POPʣ 9BNBSJO"OESPJE 9BNBSJOJ04 9BNBSJO .BD 9BNBSJO'PSNT Mono(.NETϑϨʔϜϫʔΫͷOSS࣮)Λ ج൫ͱͨ͠։ൃπʔϧΩοτ܈
Xamarin.Androidͱʁ • C#͔ΒAndroid API, Java API͕ݺͼग़ͤΔ ʮബ͍ϥούʔʯ • Activity, Intent,
ϦιʔεXMLΛී௨ʹ͑Δ • தؒίʔυ(MSIL)ͱMono VMΛΞϓϦ(apk) ʹ ಉࠝɺJava VMͱฏߦՔಇ
Xamarin.AndroidͷHello World [Activity(Label = "AppTitle", MainLauncher = true, Icon
= "@mipmap/icon")] public class MainActivity : Activity { protected override void OnCreate(Bundle state) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.Main); var btn = FindViewById<Button>(Resource.Id.btn); btn.Click += (s, e) => btn.Text = "Hello World!"; } }
Xamarin.Androidͷ࣮ߦϞσϧ "OESPJE04 +BWB7. .POP7. 9BNBSJO"OESPJE.POP ΞϓϦ $ "OESPJE04
+BWB7. "OESPJE4%, ΞϓϦ +BWB +BWB4%, AndroidωΠςΟϒ Xamarin.Android
Xamarin.iOSͱʁ • iOS SDK(CocoaTouch)͕C#͔Βݺͼ(ry • ViewController, StoryboardΛී௨ʹ͑Δ • ࣄલ(AOT)ίϯύΠϥͰϚγϯޠΛੜ͠Ξϓ Ϧ(ipa)
ʹಉࠝ
Xamarin.iOSͷ࣮ߦϞσϧ "3. "3.Ϛγϯޠ $PDPB5PVDI 9BNBSJOJ04.POP ΞϓϦέʔγϣϯ $ .POP"05ίϯύΠϥ
࣮ػ Xamarin.iOS "3. "3.Ϛγϯޠ $PDPB5PVDI ΞϓϦέʔγϣϯ 4XJGU --7.ίϯύΠϥ ࣮ػ iOSωΠςΟϒ
Xamarin.Formsͱʁ • Android, iOS, Win, ͦͷଞͰUIͷ࣮Λڞ௨Խ ͢ΔϑϨʔϜϫʔΫ • ωΠςΟϒͷUI͕༻͞ΕΔ •
.NETͷσεΫτοϓΞϓϦ։ൃख๏ʹ͍ۙ (XAML<βϜϧ>Ͱը໘Λهड़ͳͲ) • ϚΠΫϩιϑτ͜Εਪ͠
௨ৗͷAndroid։ൃͱ Xamarin.Androidͷҧ͍
౷߹։ൃڥ • Visual Studio 2017ʗfor Mac Λ͏ • AndroidΞϓϦ։ൃʹಛԽͨ͠Android Studio
ΑΓएׯޮ͕མͪΔ(ओ؍) • UIσβΠφ • XMLϦιʔεͷΠϯϥΠϯදࣔɺ • JetBrains Riderͱ͍͏৽IDEʂ
ϏϧυγεςϜ • Gradle༻Ͱ͖ͳ͍ • annotation processorΛ͏πʔϧϥΠϒϥ Ϧ༻Ͱ͖ͳ͍ • AndroidσʔλόΠϯσΟϯά •
Orma, PermissionsDispatcherͱ͔ • .NETͷϏϧυγεςϜʮMSBuildʯΛ͏
ύοέʔδཧγεςϜ • maven, JitPackͳͲ͑ͳ͍ • nuget(ʹΎʔ͛ͬͱ)Λ͏ • ׂͱ؆୯ʹ୭ͰϥΠϒϥϦΛొՄೳ
JavaͷϥΠϒϥϦ͑Δʁ • “BindingϥΠϒϥϦ”Λ࡞ΔࣄͰ༻Մೳ • “BindingϓϩδΣΫτ”ʹjarΛ์ΓࠐΉ͚ͩ • ෳࡶͳjarͩͱΧελϜϚοϐϯά͕ඞཁ • ஶ໊ͳJavaϥΠϒϥϦطʹଘࡏ͢Δ •
Google Play services, Support Libs • Picasso, Glide, OkHttp, LeakCanary, Lottie
C#ͷར ⏰ 40
ඇಉظॲཧ(async/await) • ͬͺ͜Ε • Task, Task<T>Ϋϥε • async/awaitߏจ • Rxͱ૬ޓมՄೳ
ඇಉظॲཧͷ࿈(Java) void sendZip(String src, String dest) // 1. σʔλΛμϯϩʔυͯ͠
downloadAsync(src, data -> // 2. ZIPѹॖͯ͠ zipAsync(data, zipped -> // 3. ผͳͱ͜Ζʹૹ৴ sendAsync(zipped, dest, () -> activity.runOnUiThread(() -> // ૹ৴ྃ(UIεϨου) )))); } ωετͭΒ͍ɾɾɾ
ඇಉظॲཧͷ࿈(C#) async void SendZip(string src, string dest) { //
1. σʔλΛμϯϩʔυͯ͠ var data = await DownloadAsync(src); // 2. ZIPѹॖͯ͠ var zipped = await ZipAsync(data); // 3. ผͳͱ͜Ζʹૹ৴ await SendAsync(zipped, dest); // ૹ৴ྃ(UIεϨου) } ϑϥοτʂ
ϥϜμࣜɺLINQ to Objects var list=new[]{0,1,2,3,4,5,6,7,8,9}// 0ʙ9Λ .Where(x => x
% 2 == 0) // ۮͷΈ .OrderByDescending(x => x) // ߱ॱ .Select(x => x * 10); // 10ഒ // ݁Ռ: 80 60 40 20 0 // ↑ͷ݁Ռͱ [40, 20, 10] ͱͷੵू߹Λऔಘ͢Δ var ret = list.Intersect(new[]{40,20,10}); // ݁Ռ: 40 20 ֎෦ϥΠϒϥϦʹཔΒͣͰ͖Δͷ͕ڧ͍ʂ
ͪΐͬͱnull҆શʁ // hoge ͕ null ͳΒ࣮ߦ͠ͳ͍ hoge?.DoSomething(); // hoge,
fuga ͕ null ͳΒ “none” Λฦ͢ var text = hoge?.fuga?.ToString() ?? “none"; int count = null; // ίϯύΠϧΤϥʔ int? count = null; // null ೖՄೳ ࡶͳnullνΣοΫΛ؆ུԽͰ͖Δ
vs Kotlin • ηϛίϩϯϨεͳͲͷ؆ܿͳߏจ • ڧྗͳnull҆શ • ܕਪɺϥϜμࣜ • ύλʔϯϚον
• ίϧʔνϯ(async/await) C#.NETϑϨʔϜϫʔΫͱڞʹਐԽͰ͖ΔڧΈ ݴޠͷϞμϯͩ͞ͱKotlinͷউͪ
X-PlatΞϓϦ։ൃͱ ίʔυͷڞ༗ ⏰ 30
.NETϑϨʔϜϫʔΫͰڞ௨Խ • .NETͷΫϥεϥΠϒϥϦΛͬͨίʔυ AndroidɺiOSͰڞ༗Մೳ • ྫ:JavaͷArrayList<T> → .NETͷList<T>ɺ JavaͷCalendar →
.NETͷDateTime /&5ϑϨʔϜϫʔΫʢ.POPʣ 9BNBSJO"OESPJE 9BNBSJOJ04 9BNBSJO .BD
.NETϥΠϒϥϦΛ͓͏ • ετϨʔδ - PCLStorage, Stream • σʔλϕʔε - SQLite-net,
Realm Xamarin • ௨৴ - HttpClient • JSON - Json.NET • mBaaS - Azure, AWS, Firebase
MVVM+RxʹΑΔ ϞμϯͳΞϓϦ։ൃ
MVVMύλʔϯ • View: UIύʔπͷஔͱόΠϯσΟϯά • ViewModel: ViewͷͨΊͷσʔλͱॲཧ • Model: ্هҎ֎શͯ
7JFX 7JFX .PEFM .PEFM σʔλόΠϯσΟϯά Method Call Notify
RxͱReactive Programing • Rx = Reactive Extensions • LINQͷඇಉظόʔδϣϯ •
RxJava, RxSwiftͳͲҠ২͞Εͨ • RxJavaͷਐԽRxΑΓૣ͍ • ํݴ͋ΕͲɺجຊಉ͡ • Reactive ProgramingࠓඞਢεΩϧ
XamarinʹΑΔ “X-Plat” MVVM+RxΞϓϦ։ൃ ⏰ 30
Xamarin MVVMRxͱ૬ੑ͕Α͍ʂ • RxɺϚΠΫϩιϑτൃͷOSS͔Βීٴ • MVVMɺͷσεΫτοϓΞϓϦΞʔΩ ςΫνϟͷՌ(Windows.Forms → WPF) •
.NETʹɺݟΛ࣋ͬͨਓؔ࿈ϑϨʔϜ ϫʔΫ͕๛ʹଘࡏ
MVVMϑϨʔϜϫʔΫ • Prism.Forms ࠷Hotͳਖ਼౷ϑϧελοΫϑϨʔϜϫʔΫ • MvvmCross ݹ͔͘ΒX-Plat MVVMΛࢧ͖͑ͯͨ NHKߚനΞϓϦͰ࠾༻ •
ReactiveUI MVVMʹRxΛ࣋ͪࠐΜͩ࠷ॳͷϑϨʔϜϫʔΫ
ReactiveProperty • ModelͷStreamΛViewʹ”ܨ͙”ϥΠϒϥϦ • ॳظ։ൃऀUniRxͷ࡞ऀ(a.k.a “Rxਆ”) • JavaʹҠ২ͨ͠ “RxProperty Android”
͋ΔΑ
MVVM+RxͰ࡞ͬͯΈͨ ͓: GPSड৴ΞϓϦ (14ͷҢܦΛ ඵ͓͖ʹߋ৽ ։࢝ͱఀࢭ ʮʯ͔ʮඵʯʹ Γସ͑
Android-JavaͰͷ࣮ύλʔϯ .BJO"DUJWJUZ .BJO7JFX.PEFM ViewModel View Model -PDBUJPO6TFDBTF Ңܦ 5FYU7JFX
දࣔܗࣜ 4XJUDI TUBSU 3Y+BWB MPDBUJPO 0CTFSWBCMF MPDBUJPO ։࢝ #VUUPO PO$IFDLFE PO$MJDL "OESPJEσʔλόΠϯσΟϯά -PDBUJPO"QJ -PDBUJPO.BOBHFS 'VTFE-PDBUJPO"QJ
iOS-SwiftͰͷ࣮ύλʔϯ .BJO7JFX$POUSPMMFS .BJO7JFX.PEFM ViewModel View Model -PDBUJPO6TFDBTF Ңܦ 6*5FYU'JFME
දࣔܗࣜ 6*4XJUDI TUBSU 3Y4XJGU MPDBUJPO 0CTFSWBCMF MPDBUJPO ։࢝ 6*#VUUPO PO4XJUDI TUBSU 4XJGU#POE -PDBUJPO"QJ $--PDBUJPO.BOBHFS
Xamarin.FormsͰͷ࣮ύλʔϯ .BJO1BHF .BJO7JFX.PEFM ViewModel View Model -PDBUJPO6TFDBTF Ңܦ -BCFM
දࣔܗࣜ 4XJUDI 4UBSU 3FBDUJWF&YUFOTJPOT -PDBUJPO 0CTFSWBCMF -PDBUJPO ։࢝ #VUUPO *T%NT'PSNBU 4UBSU 9BNBSJO'PSNTσʔλόΠϯσΟϯά -PDBUJPO"QJ -PDBUJPO.BOBHFS <Inject> -PDBUJPO"QJ $--PDBUJPO.BOBHFS
.BJO1BHF .BJO7JFX.PEFM ViewModel View Model -PDBUJPO6TFDBTF Ңܦ -BCFM දࣔܗࣜ
4XJUDI 4UBSU 3FBDUJWF&YUFOTJPOT -PDBUJPO 0CTFSWBCMF -PDBUJPO ։࢝ #VUUPO *T%NT'PSNBU 4UBSU 9BNBSJO'PSNTσʔλόΠϯσΟϯά -PDBUJPO"QJ -PDBUJPO.BOBHFS <Inject> -PDBUJPO"QJ $--PDBUJPO.BOBHFS AndroidσʔλόΠϯσΟϯά SwiftBond ↓ Xamarin.Forms σʔλόΠϯσΟϯά Xamarin.FormsͰͷ࣮ύλʔϯ
.BJO1BHF .BJO7JFX.PEFM ViewModel View Model -PDBUJPO6TFDBTF Ңܦ -BCFM දࣔܗࣜ
4XJUDI 4UBSU 3FBDUJWF&YUFOTJPOT -PDBUJPO 0CTFSWBCMF -PDBUJPO ։࢝ #VUUPO *T%NT'PSNBU 4UBSU 9BNBSJO'PSNTσʔλόΠϯσΟϯά -PDBUJPO"QJ -PDBUJPO.BOBHFS <Inject> -PDBUJPO"QJ $--PDBUJPO.BOBHFS RxJava RxSwift ↓ Reactive Extensions Xamarin.FormsͰͷ࣮ύλʔϯ
.BJO1BHF .BJO7JFX.PEFM ViewModel View Model -PDBUJPO6TFDBTF Ңܦ -BCFM දࣔܗࣜ
4XJUDI 4UBSU 3FBDUJWF&YUFOTJPOT -PDBUJPO 0CTFSWBCMF -PDBUJPO ։࢝ #VUUPO *T%NT'PSNBU 4UBSU 9BNBSJO'PSNTσʔλόΠϯσΟϯά -PDBUJPO"QJ -PDBUJPO.BOBHFS <Inject> -PDBUJPO"QJ $--PDBUJPO.BOBHFS andoid:LocationaManager ios:CLLocationManager ↓ ϓϥοτϑΥʔϜݻ༗APIΛ ࣮ͬͨΛDI (Dependency Injection) Xamarin.FormsͰͷ࣮ύλʔϯ
.BJO1BHF .BJO7JFX.PEFM ViewModel View Model -PDBUJPO6TFDBTF Ңܦ -BCFM දࣔܗࣜ
4XJUDI 4UBSU 3FBDUJWF&YUFOTJPOT -PDBUJPO 0CTFSWBCMF -PDBUJPO ։࢝ #VUUPO *T%NT'PSNBU 4UBSU 9BNBSJO'PSNTσʔλόΠϯσΟϯά -PDBUJPO"QJ -PDBUJPO.BOBHFS <Inject> -PDBUJPO"QJ $--PDBUJPO.BOBHFS ڞ௨ԽͰ͖ͳ͍ͷ͚ͩ͜͜ Xamarin.FormsͰͷ࣮ύλʔϯ
X-Platڞ௨ԽͰ͖ΔʁͰ͖ͳ͍ʁ • ViewModelɿશʹڞ௨ԽͰ͖Δ • Model • Usecaseɿશʹڞ௨ԽͰ͖Δ • APIɿҰ෦ڞ௨ԽͰ͖ΔɺͰ͖ͳ͚ΕDI •
ViewɿҰ෦ڞ௨ԽͰ͖ΔɺͰ͖ͳ͚ΕDI ⏰ 20
ڞ௨Խࣄྫ1: B2B͚ ंӡߦཧΞϓϦ • 20ը໘ • ڞ௨Ͱͳ͍ॲཧ: GPS, Push௨,
Ի࠶ੜ, Toast • ૯ίʔυߦ: 22,816 Android:9% 2,134ߦ iOS:6% 1,407ߦ ڞ௨:85% 19,275ߦ
ڞ௨Խࣄྫ2: ΤΠνɾΤεূ݊ εϚג • 70ը໘ • ViewC#ɺViewModelͱModel F# Λ༻
• ૯ίʔυߦ: 72,445 Android:3% 2,130ߦ iOS:4% 2,897ߦ ڞ௨:93% 67,418ߦ JXUG#17ʮূ݊औҾΞϓϦͱNote app࡞ͬͯΈͨʯΑΓ
Open Xamarin, ɹɹOpen Microsoft • Xamarin.Android .iOS .Forms શͯOSS •
.NET Core • .NETϑϨʔϜϫʔΫ(ͷҰ෦)ΛOSS&X-PlatԽ • AWS LambdaGCP͕.NET/C#ʹରԠ ϚΠΫϩιϑτ = ϓϩϓϥΠΤλϦ .NET = Windows ඇৗࣝʂ
Xamarinͷ͍Ͳ͜Ζ ʙۜͷؙͳ͍ΑͶʙ
Xamarin͕͍͍ͯͳ͍έʔε • AndroidɺiOSͷτοϓΤϯδχΞ͕ډΔ ˠAndroidͷΤʔεʹXamarinෆཁ • ΞϓϦͷαΠζΛؾʹ͢ΔϓϩμΫτ ˠ.NETϥϯλΠϜΛಉࠝ͢ΔͷͰ༰ྔ૿͑Δ • फڭ্ͷཧ༝ →͏Μ͏ΜͦΕ͋ΔΑͶ
XamarinΛ͏͖έʔε • B2BͳϞόΠϧɾλϒϨοτΞϓϦ • Win, Android, iOSͰڞ௨ϩδοΫΛ࠷େԽ • ӡ༻อकίετ㽊ɺཁһ֬อ •
ελʔτΞοϓاۀ • ϏδωεϞσϧݕূ༻ʹαΫοͱ։ൃ • AndroidͱiOSࢢʹಉ࣌ೖ • ϑΟʔυόοΫɾϧʔϓΛૉૣ͘ճͤΔ
·ͱΊ
Xamarin.AndroidͰ࢝ΊΔ ɹɹɹɹX-PlatϞόΠϧΞϓϦ։ൃ 1. JavaͷAndroidΞϓϦΛɺXamarin.Android ʹҠ২ͯ͠ΈΑ͏ 2. iOSΞϓϦΛXamarin.iOSͰ࡞ͬͯΈΑ͏ 3. ڞ௨ϩδοΫΛ.NETͰॻ͖ͯ͠ΈΑ͏ 4.
Xamarin.FormsͰը໘ڞ௨ʹͯ͠ΈΑ͏ 5. MVVMRxΛద༻ͯ͠ΈΑ͏
Android iOS .NET ͥΜͿֶΜͰ C# Ͱ D.R.Y ͢Δͷ͕
Xamarin
ଓ͖ʮٕज़ॻయ̎ʯͰʂ • ͏-13ʮXamaritansʢ͟·ΓͨΜͣʣʯ • Xamarinͷ࠷ઌใΛ·ͱΊͨຊΛ͠·͢ • ٕज़ॻయ(in χίχίձٞ2017)ʂ
͝ਗ਼ௌ ͋Γ͕ͱ͏͍͟͝·ͨ͠$