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 で始めるクロスプラットフォームモバイルアプリ開発 #j...
Search
amay077
April 14, 2017
Programming
0
600
Xamarin.Android で始めるクロスプラットフォームモバイルアプリ開発 #jaghama
2017/4/15, はじめてのXamarin with D - connpass -
https://jaghama.connpass.com/event/54228/
の発表資料です。
amay077
April 14, 2017
Tweet
Share
More Decks by amay077
See All by amay077
愛知県新型コロナ対策サイト(非公式)の紹介
amay077
0
270
愛知県コロナ対策サイトが立ち上がってから
amay077
0
70
Xamarin.Forms Hot Reload のススメ
amay077
0
820
クロスプラットフォームモバイルアプリ開発ツール総ざらい2019 〜Titanium Mobile から Kotlin/Native まで〜 #droidkaigi
amay077
11
9.9k
ハムスター検出器を1日で作ってみた #NGK2018B
amay077
1
1k
App Center から Azure Pipeline に乗り換えた話
amay077
0
1.3k
Xamarin.Forms.GoogleMaps について
amay077
0
1.4k
Xamarin.Android で始めるクロスプラットフォームモバイルアプリ開発 #jxug
amay077
0
880
Xamarin.Android で始めるクロスプラットフォームモバイルアプリ開発 #droidkaigi #droidkaigi1
amay077
3
3.5k
Other Decks in Programming
See All in Programming
Modern Angular: Renovation for Your Applications
manfredsteyer
PRO
0
220
Vue3の一歩踏み込んだパフォーマンスチューニング2024
hal_spidernight
3
3.2k
デプロイを任されたので、教わった通りにデプロイしたら障害になった件 ~俺のやらかしを越えてゆけ~
techouse
52
32k
詳細解説! ArrayListの仕組みと実装
yujisoftware
0
490
役立つログに取り組もう
irof
27
8.8k
Realtime API 入門
riofujimon
0
120
ECSのサービス間通信 4つの方法を比較する 〜Canary,Blue/Greenも添えて〜
tkikuc
11
2.3k
Generative AI Use Cases JP (略称:GenU)奮闘記
hideg
0
170
cXML という電子商取引の トランザクションを支える プロトコルと向きあっている話
phigasui
3
2.3k
Identifying User Idenity
moro
6
8.2k
Why Spring Matters to Jakarta EE - and Vice Versa
ivargrimstad
0
1.1k
OpenTelemetryでRailsのパフォーマンス分析を始めてみよう(KoR2024)
ymtdzzz
4
1.7k
Featured
See All Featured
Designing for Performance
lara
604
68k
Speed Design
sergeychernyshev
24
570
Building an army of robots
kneath
302
42k
Designing on Purpose - Digital PM Summit 2013
jponch
115
6.9k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
800
Thoughts on Productivity
jonyablonski
67
4.3k
The Invisible Side of Design
smashingmag
297
50k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
Product Roadmaps are Hard
iamctodd
PRO
48
10k
Become a Pro
speakerdeck
PRO
24
5k
Code Review Best Practice
trishagee
64
17k
Optimizing for Happiness
mojombo
376
69k
Transcript
Xamarin.AndroidͰ࢝ΊΔ ΫϩεϓϥοτϑΥʔϜ ϞόΠϧΞϓϦ։ൃ 2017.4.15 ͡ΊͯͷXamarin with D ຊAndroidͷձদࢧ෦
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
ٕज़ॻయ̎ͰXamarinຊചʂ • Essential Xamarin Yin/Yang (ӄ/ཅ) • ͋Γ·͢ʂ
࣍ʮٕज़ॻయʯͩʂ • 2(4/30)ͷΈ ͋-12 • Essential Xamarin Yin/Yang (ӄ/ཅ) ֤1,000ԁ
• ଈചձ͜Ε͕࠷ޙʁ
͝ਗ਼ௌ ͋Γ͕ͱ͏͍͟͝·ͨ͠$