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
600件のPull RequestからみたXamarinのはまりどころ
Search
Nobuhiro Ito
May 07, 2016
Technology
3
4.3k
600件のPull RequestからみたXamarinのはまりどころ
2016/05/07(Sat) Japan Xamarin User Group #13 Xamarinのすべて!
Nobuhiro Ito
May 07, 2016
Tweet
Share
More Decks by Nobuhiro Ito
See All by Nobuhiro Ito
Introduction of Aizome - 多言語対応とスタイル適用を両立する書式付き文字列ライブラリ
iseebi
0
110
Bitriseで本をビルドする / Build a book with Bitrise
iseebi
0
160
BitriseでmacOSアプリをビルドする / Build macOS apps with Bitrise
iseebi
1
800
iOS/Androidアプリ転送ツール TransporterPadの紹介
iseebi
0
6.1k
Apple Developer Enterprise Program でどこまでいけるのか
iseebi
0
780
ReactiveProperty を使ったアプリの設計に Realm Xamarin を組み合わせる
iseebi
0
660
ReactiveProperty で Xamarin アプリの作り方が変わった
iseebi
3
1.7k
Yet Another Cross Platform Development
iseebi
0
4.2k
XamarinでPDFを作る
iseebi
1
1.7k
Other Decks in Technology
See All in Technology
今!ソフトウェアエンジニアがハードウェアに手を出すには
mackee
11
4.5k
S3アクセス制御の設計ポイント
tommy0124
2
190
Agile PBL at New Grads Trainings
kawaguti
PRO
1
390
おやつは300円まで!の最適化を模索してみた
techtekt
PRO
0
290
スマートファクトリーの第一歩 〜AWSマネージドサービスで 実現する予知保全と生成AI活用まで
ganota
1
200
自作JSエンジンに推しプロポーザルを実装したい!
sajikix
1
170
LLMを搭載したプロダクトの品質保証の模索と学び
qa
0
1k
ZOZOマッチのアーキテクチャと技術構成
zozotech
PRO
3
1.4k
Automating Web Accessibility Testing with AI Agents
maminami373
0
1.2k
AWSを利用する上で知っておきたい名前解決のはなし(10分版)
nagisa53
9
2.9k
バイブスに「型」を!Kent Beckに学ぶ、AI時代のテスト駆動開発
amixedcolor
2
510
バッチ処理で悩むバックエンドエンジニアに捧げるAWS Glue入門
diggymo
3
180
Featured
See All Featured
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
840
Testing 201, or: Great Expectations
jmmastey
45
7.6k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
18
1.1k
How STYLIGHT went responsive
nonsquared
100
5.8k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3.1k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
KATA
mclloyd
32
14k
Site-Speed That Sticks
csswizardry
10
810
YesSQL, Process and Tooling at Scale
rocio
173
14k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
31
2.2k
GraphQLとの向き合い方2022年版
quramy
49
14k
Done Done
chrislema
185
16k
Transcript
600݅ͷPull Request ͔ΒΈͨ Xamarin ·ΓϙΠϯτ Nobuhiro Ito / Fenrir Inc.
@ Japan Xamarin User Group Conference #13, 2016/05/07(Sat)
@iseebi Nobuhiro Ito Fenrir Inc. Smartphone App Engineer http://iseebi.hatenablog.com/
ձࣾͱͯ͠Xamarinྺ2Ҏ্ ా͞Μ͕XamarinऔΓѻ͍͡ΊΔલ͔ΒͬͯΔ
MvvmCross Ψν ͨͩ࠷ۙͬͱଞͷͷΛࢼ͍ͨ͠ͱࢥͬͯΔ… ※px୯ҐͰϨΠΞτࢦ͕ࣔඈΜͰ͘ΔͷͰFormsͰରॲͰ͖ͳ͍
࠷ۙͷ͓ࣄ ΞϓϦͷ։ൃͷ͔ͨΘΒɺύοέʔδͷϓϩμΫτΦʔφʔͬͯ·͢ɻ
͋ΔϓϩδΣΫτͷ͓Λ͠·͢
ϓϩδΣΫτͷཧମ੍ͷมԽ • 2011, 2012 ωΠςΟϒ / Subversion (2012ͷ్த͔ΒgitҠߦ), Redmine •
2013, 2014 Xamarin / git, Redmine, Backlog, TeamGantt • 2015 Xamarin / GitHub Enterprise, Redmine, Backlog, TeamGantt
GitHub Enterprise ʹͯ͠Α͔ͬͨ͜ͱ • શ෦ Pull Request ͰϨϏϡʔͰ͖Δ • ͋ͱ͔Β༷ʑͳ͜ͱΛৼΓฦΔ͜ͱ͕Ͱ͖Δɻ
͋ͱ͔ΒৼΓฦΔ͜ͱ͕Ͱ͖Δ • ίϛοτͷճͱ͔ • ͲΜͳίϛοτΛ͔ͨ͠ͱ͔ (શ෦ Pull Request ͰݟΕΔ)
None
4ϲ݄Ͱͪΐ͏ͲͽͬͨΓPR 600݅ ࠓ͜ͷத͔Β ಛʹʮۤ͠Μͩͳʔʯͱ͍͏ͱ͜ΖΛ ͔͍ͭ·ΜͰ͝հ
ͦͷ1 HTTPϋϯυϥෆ҆ఆࣄ݅
Hello, ModernHttpClient • աڈͷ։ൃ͔ΒɺHttpWebRequest ͩͱ Android Ͱ ·Εʹ DNS
͕1΄ͲҾ͚ͳ͘ͳΓɺ௨৴Ͱ͖ͳ͘ͳΔ͜ͱ͕Θ͔͍ͬͯͨɻ • 2015ModernHttpClientΛ͏͜ͱܾΊ͍ͯͨɻ • HttpClient ͷҾʹ͢ HttpClientHandler ͱͯ͢͠ NativeMessageHandler Λఏڙͯ͘͠ΕΔɻ • iOS 9 ͷ ATS ରԠͱͯ͠ඞਢͩͬͨɻ
iOS 8 ͔͋ΜΜ… • ModernHttpClient ͷಋೖࣗମΘΓͱ͢ΜͳΓͰ͖ͨɻ • AutomaticDecompression = true
Λࢦఆ͍ͯ͠Δͱ iOS ͰΫϥογϡ͢Δͱ͔͋ͬͨɻ • ͔͠͠ɺࠓ iOS 8 Ͱ HTTP ͕௨Βͳ͘ͳΔݱ͕ൃੜ͢Δ…
CFNetworkHandler…ࠓiOS9͕͔͋Μ… • ModernHttpClientಉ༷ʹɺHttpClientHandlerͱͯ͑͠Δ System.Net.Http.CFNetworkHandler ͕ೖ͍ͬͯͨͷͰ͏ɻ • iOS 8Ͱ҆ఆ͢Δ͕ɺiOS 9 Ͱ
https ͕௨Βͳ͘ͳͬͨɻ • iOS 8 Ҏલ CFNetworkHandlerɺ ͦΕҎ֎Ͱ NativeMessageHandler Λ ༻͢ΔΑ͏ʹ͢Δ͜ͱͰղܾɻ • NSUrlSessionHandler/AndroidClientHandler ͕ඪ४ࡌ͞Ε(Δ|ͨ)Β͍͠ͷͰظɻ J04PS&BSMJFS $'/FUXPSL)BOEMFS J04 /BUJWF.FTTBHF)BOEMFS "OESPJE /BUJWF.FTTBHF)BOEMFS
ͦͷ2 Content Description จࣈԽ͚ࣄ݅ @Android
ࣗಈςετ͠·͠ΐ͏…·͓ͨ·͔͑Galaxy! • Android ͷ UI ςετΛ͢Δ͜ͱʹͳ͍ͬͯͨͷͰɺContent Description Λࢦఆ͍ͯͨ͠ɻ • ຊͷἧ͑ͷͰ
Xamarin Test Cloud Ͱͳ͘ɺ Remote TestKit ͱUIAutomator ͷΈ߹Θͤɻ • ຊޠͷ Content Description Λࢦఆ͍ͯ͠Δͱ Galaxy S6 edge Ͱ͜ͱ͝ͱ͘??????????????ʹจࣈԽ͚ɻ • ݁ہӳޠࢦఆ͠ɺϦϦʔεલʹ͢͜ͱͰղܾɻXTC ͬͯͯʹͳΔ͔ʁ
ͦͦGalaxyͱXamarinͷ૬ੑ͕ѱ͍ • جຊతʹԿ͔͋Δͷ GalaxyɻS4, S5, S6 શ෦Ϡό͍ɻ • Galaxy S4
4.2.1 ͕ಛʹϠό͍ɻଞͷͰಈ͍͍ͯΔίʔυ͕ී௨ʹམͪΔɻ • ͦͯ͜͠ͷͳΜͱUSBσόοάͰ͖ͳ͍ʢʂʣ • ͨͩɺ͍͕ͭ͜མ͍ͪͯΔͷ্࣮ؒҧ͍ͬͯͨͱ͍͏͜ͱ͔Γͩͬͨɻ • ͖ͬͪΓςετ͍ͨ͠Ϛκͳํ1ήοτ͓ͯ͘͠ͱྑ͍͔ɻ
ͦͷ3 ARM64Ͱଈࢮࣄ݅ @Android
64bit ͷ .so ͕͋Δͱ ABI 64bit ͳ͍ͱࢮ͵ • Android൛ͰRealmґଘ͍ͯ͠ΔωΠςΟϒϥΠϒϥϦΛ͍ͬͯͨɻ
• XamarinͰ͍ͬͯͳ͔ͬͨɻωΠςΟϒϥΠϒϥϦࢀর͍ͯ͠ΔͷΈɻ • ͢ΔͱGalaxy S6ͳͲͷARM64Ͱଈࢮ͢Δ • libmonodroid.so͕ͳ͍ͱग़ͨɻΞϓϦࣗମABI͍࣋ͬͯͳ͍͕ɺ Realm ͷωΠςΟϒϥΠϒϥϦͷ .so ͕ల։͞Εͨ͜ͱͰඞཁʹͳͬͯ͠·ͬͨɻ • ΞϓϦଆ64bit ABI Λαϙʔτͤ͞Δ͜ͱͰղܾɻ
ͦͷ4 ऴྃͨͣ͠ͷը໘ͷը૾͕ ͬͯͯϝϞϦෆࣄ݅
͋ͪͪ͜Ͱىͬͨ͜ • ը૾͕ϝϞϦ্ʹͬͯϦʔΫ / OOM • ಛʹ Android ͷ AnimationDrawable
͕͠Ϳͱ͔ͬͨ
ίʔυͷதͰ࡞ͬͨΦϒδΣΫτඞͣղ์ʂ • ϑΟʔϧυʹࢀরΛ࣋ͬͨ ΦϒδΣΫτ ඞͣ Dispose/ࢀর֎͢͠Δ UIButton appendButton; public
override void ViewDidLoad () { base.ViewDidLoad (); appendButton = new UIButton(new CGRect(10,10, 200, 48)); View.AddSubview(appendButton); } protected override void Dispose(bool disposing) { if (disposing) { if (appendButton != null) { appendButton.Dispose(); appendButton = null; } } base.Dispose(disposing); }
iOSͷ߹: Image,Layer ͷதղ์͢Δ • ϓϩϑΝΠϥͰΈͨͱ͖ը૾͕͍ͬͯͨ͜ͱ͕͋Δ • ͦ͏͍͏ͱ͖ ImageView ͷ Image,
Layer.SubLayers ۭʹͯ͠ɺ RemoveFromSuperview ͢Δͱྑ͍ɻ if (HogeImageView != null) { HogeImageView.Image = null; if (HogeImageView.Layer != null) { HogeImageView.Layer.Sublayers = null; } HogeImageView.RemoveFromSuperview(); }
Android: AnimationDrawable ͷ State ղ์ • AnimationDrawable Λͬͨ߹ɺ தͷϑϨʔϜͷBitmap͕ ղ์͞Εͳ͍ͷͰɺ
ࣗͰதΛRecycleͯ͠ SetState Ͱࢀরղ์ͯ͠Δɻ void RecycleAnimationDrawable() { if (_drawableAnimation == null) { return; } for (int i = 0; i < _drawableAnimation.NumberOfFrames; ++i) { var frame = _drawableAnimation.GetFrame(i); var bitmap = frame as BitmapDrawable; if ((bitmap != null) && !bitmap.IsRecycled) { bitmap.Recycle(); bitmap.Dispose(); } frame.Callback = null; } _drawableAnimation.Callback = null; _drawableAnimation.SetState(new int[] { }); _drawableAnimation = null; }
ͦͷ5 MvvmCross ͷ ListViewAdapter Viewੜ࣌ʹແବʹηοτ͕ಈ͘ @Android
MvxListView ͷ MvxAdapter • MvxListView ༻ʹόΠϯσΟϯάՄೳͳ ViewItem Λఏڙ͢Δ Adapter •
ͦͷ··͏͜ͱɺΧελϜͯ͠͏͜ͱͰ͖Δɻ • CreateBindableView ΛΦʔόʔϥΠυ͢Δɻ • ͳ͔ͥ CreateBindableView ͷੜ࣌ʹΫϥογϡͯ͠͠·͏͜ͱ͕͋ͬͨɻ • ߲ View ͷ MvxImageView ͷதͰ SetImageDrawable(null) ͕ಈ͍͍ͯͨɻ
CreateBindableView ൈ͚Δલʹ Binding ߋ৽͞ΕΔͷμϝ protected override IMvxListItemView CreateBindableView(object dataContext, int
templateId) { var itemView = base.CreateBindableView(dataContext, templateId); var view = itemView as View; if (view != null) { var imageView = view.FindViewById<MvxImageView>(Resource.Id.timeline_image); imageView.ErrorImageResourceId = Resource.Drawable.img_live_object_loadfail; } return itemView; } %BUB$POUFYUͷ४උ͕ऴΘͬͯͳ͍λΠϛϯάͰݺΕΔ ˠը૾͕OVMM͕ೖͬͯ͘ΔՄೳੑ͕͋Δ
DataContext ॳظԽऴΘ͔ͬͯΒܨ͙ protected override IMvxListItemView CreateBindableView(object dataContext, int templateId) {
var itemView = base.CreateBindableView(null, templateId); var view = itemView as View; if (view != null) { var imageView = view.FindViewById<MvxImageView>(Resource.Id.timeline_image); imageView.ErrorImageResourceId = Resource.Drawable.img_live_object_loadfail; } itemView.DataContext = dataContext; return itemView; }
ͦͷ6 iOS 8 ͰىಈޙҰൃͷ γϟολʔԻ͕໐Βͳ͍
iOS 8 ͷγϟολʔ໐Βͳ͍όά • ຊࠃ͚ͷ iPhone ͰαΠϨϯτϞʔυʹ͍ͯͯ͠ γϟολʔԻ͕ͳΔ • ͔͠͠ɺiOS
8 Ͱ OS ىಈޙ 1 ճͷγϟολʔԻ͕໐Βͳ͍ɻ • Α͘ΒΕͨ iOS ࣗମͷόά
iOS 8 ͷॳճͷΈɺ ڧ੍తʹγϟολʔԻΛ໐Β͢ (Βͳ͍ํ͕ྑ͍) • iOS ΈࠐΈͷޮՌԻΛ໐Β͢ AudioToolBox.SystemSound •
1108 ൪Λࢦఆ͢ΔͱɺΧϝϥͱಉ݅͡Ͱγϟολʔ͕໐Δ • iOS 8 ͷఆ UIDevice.CurrentDevice.CheckSystemVersion ͰՄೳɻ • ౾ࣝɿ͜ͷϝιου Xamarin ಠ֦ࣗு
iOS 8 ͷॳճͷΈɺ ڧ੍తʹγϟολʔԻΛ໐Β͢ (Βͳ͍ํ͕ྑ͍) needDummyShutterSound = UIDevice.CurrentDevice.CheckSystemVersion(8, 0)
&& !UIDevice.CurrentDevice.CheckSystemVersion(9, 0) && !dummyShutterSoundPlayed; : : if (needDummyShutterSound) { needDummyShutterSound = false; dummyShutterSoundPlayed = true; var sound = new AudioToolbox.SystemSound(1108); sound.PlaySystemSound(); } J04Ҏ্ɺJ04Ҏ্Ͱͳ͍ ͔ͭ·ͩ໐Βͯ͠ͳ͍ TUBUJDϑΟʔϧυ ൪ͷγεςϜαϯυΛ໐Β͢
·ͱΊ
ओͳ·ΓϙΠϯτճආํ๏ • HTTP௨৴पΓ ModernHttpClient (͘͠NSUrlSessionHandler/AndroidSessionHandler)Λ͏ɻ iOS 8 ҎԼ CFNetworkHandler
Λͬͨ΄͏͕Αͦ͞͏ɻ • ࢀরͨ͠ωΠςΟϒΦϒδΣΫτ͖ͪΜͱղ์͢Δɻ ಛʹը૾पΓղ์ʹؾΛ͚ͭΔɻ • Galaxyɺઈର͍ͭ͜Կ͔͋Δɻ1 ͋Δͱσόοάʹศརɻ Xamarin Test Cloud ʹ͍ͬͺ͍͋Γͦ͏͔ͩΒ׆༻͠Α͏ɻ
͍͞͝ʹ