Slide 1

Slide 1 text

Pie Meets Py - PythonͰAndroidΞϓϦΛͭ͘Ζ͏ 2019-09-16 (PyCon JP 2019) ௕୩৔ ५໵

Slide 2

Slide 2 text

ࣗݾ঺հ • ௕୩৔ ५໵ (͸ͤ͹ ͡ΎΜ΍) • ֤छSNSͰ͸ 7pairs Ͱ׆ಈத • ޷͖ͳେࡕۅӂ͸தଜ߶໵ " / ޷͖ͳ෋࢜େֶ͸֎࡚मଡ # • ͓࢓ࣄͰ͸Android (Java / Kotlin) / iOS (Objective-C / Swift) ͕த৺ • ͋·ΓҰൠతͱ͸ݴ͑ͳ͍Pythonͷ࢖͍ํΛ໛ࡧ͢Δͷ͕େ޷͖ • PyCon JP 2018Ͱ͸Transcryptʹ͍ͭͯൃද • https://speakerdeck.com/7pairs

Slide 3

Slide 3 text

ஶॻ Chalice, Transcrypt, pytest, SeleneΛར༻ͯ͠
 αʔόʔϨεΞϓϦΛ࣮૷ɾςετ͢ΔຊͰ͢ AmazonଞͰઈࢍൢചதʂ

Slide 4

Slide 4 text

͜ͷηογϣϯͰ࿩͢͜ͱ • PythonʹΑΔAndroidΞϓϦͷ։ൃ؀ڥ • ֤։ൃ؀ڥͷ௕ॴɾ୹ॴ • ։ൃ؀ڥͷબͼํ

Slide 5

Slide 5 text

͜ͷηογϣϯͰ࿩͞ͳ͍͜ͱ • ֤։ൃ؀ڥͰͷৄࡉͳ࣮૷ํ๏ • ֤։ൃ؀ڥͰͷςετํ๏

Slide 6

Slide 6 text

͜ͷηογϣϯͷΰʔϧ • AndroidΞϓϦ։ൃʹڵຯΛ͍࣋ͬͯͨͩ͘ • Pythonͷଟ༷ͳՄೳੑΛ஌͍ͬͯͨͩ͘ • ύʔςΟͰࢲ͕΅ͬͪʹͳΒͳ͍

Slide 7

Slide 7 text

ͳͥ “Pie Meets Py” ʁ

Slide 8

Slide 8 text

PieͱPyͷൃԻ (ถࠃӳޠ) • Pieʲpάɪʳ • Pythonʲpάɪθɑnʳ

Slide 9

Slide 9 text

Pieͱ͸ʁ • Android 9.0ͷίʔυωʔϜ • Android 1.5 (3൪໨ͷόʔδϣϯ) Ҏ߱ 
 ֤όʔδϣϯʹ͸ΞϧϑΝϕοτॱʹ 
 ͓՛ࢠͷίʔυωʔϜ͕͚ͭΒΕ͍ͯΔ

Slide 10

Slide 10 text

Android 1.5 Cupcake

Slide 11

Slide 11 text

Android 1.6 Donut

Slide 12

Slide 12 text

Android 2.0 Eclair

Slide 13

Slide 13 text

Android 2.2 Froyo

Slide 14

Slide 14 text

Android 2.3 Gingerbread

Slide 15

Slide 15 text

Android 3.0 - 3.2 Honeycomb

Slide 16

Slide 16 text

Android 4.0 Ice Cream Sandwich

Slide 17

Slide 17 text

Android 4.1 - 4.3 Jelly Bean

Slide 18

Slide 18 text

Android 4.4 Kitkat

Slide 19

Slide 19 text

Android 5.0 - 5.1 Lollipop

Slide 20

Slide 20 text

Android 6.0 Marshmallow

Slide 21

Slide 21 text

Android 7.0 - 7.1 Nougat

Slide 22

Slide 22 text

Android 8.0 - 8.1 Oreo

Slide 23

Slide 23 text

Android 9.0 Pie

Slide 24

Slide 24 text

Android 10 • 2019೥9݄3೔ϦϦʔε • PixelγϦʔζ͔Βॱ࣍഑৴ • ͓՛ࢠͷίʔυωʔϜ͕ഇࢭ $ • ੈքதͷ͢΂ͯͷϢʔβʔ͕ 
 ಉ͡Α͏ʹೝࣝͰ͖Δ໊લͰ͸ͳ͍ͨΊ

Slide 25

Slide 25 text

ͳͥPythonͰAndroid։ൃʁ

Slide 26

Slide 26 text

2018೥य़ͷϫΠক

Slide 27

Slide 27 text

ڝ߹ͦ͠͏ͳྖҬ • WebΞϓϦͷόοΫΤϯυ • ΫϩʔϦϯάʗεΫϨΠϐϯά • σʔλ෼ੳɾՄࢹԽ • ࣗવݴޠॲཧ

Slide 28

Slide 28 text

ͤ΍ʂAltJSͰCfPग़ͨ͠Ζʂ

Slide 29

Slide 29 text

PyCon JPʹAltJSͷηογϣϯ͕ര஀

Slide 30

Slide 30 text

2019೥य़ͷϫΠক

Slide 31

Slide 31 text

ڝ߹ͦ͠͏ͳྖҬ • WebΞϓϦͷόοΫΤϯυ • (ࣗಈ) ςετ • σʔλ෼ੳɾՄࢹԽ • ࣗવݴޠॲཧ

Slide 32

Slide 32 text

ͤ΍ʂAndroidͰCfPग़ͨ͠Ζʂ

Slide 33

Slide 33 text

PyCon JPʹAndroidͷηογϣϯ͕ര஀

Slide 34

Slide 34 text

PyCon mini HiroshimaͰ΋ൃද͠·͢

Slide 35

Slide 35 text

Why did you want to develop
 Android apps in Python ?

Slide 36

Slide 36 text

Because it's there.

Slide 37

Slide 37 text

։ൃ؀ڥ

Slide 38

Slide 38 text

બఆͷ৚݅ • ࣮૷ݴޠ͕PythonͰ͋Δ • ࣮༻ʹ଱͑Δ଎౓Ͱಈ࡞͢Δ • Google Play StoreʹϦϦʔεͰ͖Δ

Slide 39

Slide 39 text

͝঺հ͢Δ։ൃ؀ڥ • React Native + Transcrypt • Kivy • Chaquopy

Slide 40

Slide 40 text

React Native + Transcrypt

Slide 41

Slide 41 text

React Native • Facebook͕։ൃ͍ͯ͠ΔΦʔϓϯιʔεͷ 
 ϞόΠϧΞϓϦέʔγϣϯϑϨʔϜϫʔΫ • جຊతʹReactͱಉ༷ͷݪཧͰಈ࡞͢Δ͕ 
 ඳը͸֤OSͷωΠςΟϒAPIΛར༻͢Δ • ࣮૷ʹ͸JavaScriptΛར༻͢Δ • Android / iOS / UWPʹରԠ

Slide 42

Slide 42 text

Transcrypt • PythonΛJavaScriptʹม׵͢ΔAltJS • ެࣜαΠτᐌ͘ “subset of Python” Ͱ͋Γ 
 ͢΂ͯͷػೳΛαϙʔτ͍ͯ͠ΔΘ͚Ͱ͸ͳ͍ • Ұ෦ͷඪ४ϥΠϒϥϦ͕ར༻Ͱ͖ͳ͍ͳͲ • JavaScriptͷॲཧΛγʔϜϨεʹݺͼग़ͤΔ • JavaScriptͷ֎෦ύοέʔδ΋ར༻Մೳ

Slide 43

Slide 43 text

AltJSͱͯ͠ͷPython • PyCon JP 2018ʹͯ 
 Transcryptʹ͍ͭͯൃද͠·ͨ͠ • https://www.youtube.com/watch?v=zGqUysiC1xA&t • https://speakerdeck.com/7pairs/pycon-jp-2018

Slide 44

Slide 44 text

React Native + Transcrypt • React Native͸ϓϩάϥϜΛ 
 JavaScriptͰ࣮૷͢Δ • Transcrypt͸PythonΛJavaScriptʹม׵͢Δ • ૊Έ߹ΘͤΕ͹PythonͰReact Nativeͷ 
 ϓϩάϥϜ͕ॻ͚ΔͷͰ͸ʁ

Slide 45

Slide 45 text

ݕূ݁Ռ • ΤϯτϦϙΠϯτ (App.js) Λআ͍ͯ 
 ͢΂ͯPythonͰ࣮૷͕Ͱ͖·ͨ͠ʂ %

Slide 46

Slide 46 text

Positive ! • ιʔεͷߋ৽Λ؂ࢹͯ͠τϥϯεύΠϧ͢Ε͹ 
 Fast RefreshͷԸܙʹ͔͋ͣΕΔ • ܕώϯτΛ͚ͭΔ͜ͱͰ
 τϥϯεύΠϧ࣌ʹܕνΣοΫ͕Մೳ

Slide 47

Slide 47 text

TypeScriptͰे෼ͳͷͰ͸ &

Slide 48

Slide 48 text

TranscryptͷܕνΣοΫ def concat(a: str, b: str) -> str: return f"{a}-{b}" # 33-4 concat("33", "4") # error: Argument 2 to "concat" has # incompatible type "int"; expected "str" concat("33", 4)

Slide 49

Slide 49 text

Negative $ • Pythonͷlambdaࣜͷ੍ݶʹਏΈ͕͋Δ • ͋Δఔ౓ͷن໛ͷॲཧΛॻ͖͍ͨέʔε͕ଟ͍ • JSXͷѻ͍ʹਏΈ͕͋Δ • ֎෦ͷJSXίϯύΠϥΛݺͼग़ͯ͠ 
 ͦͷ݁ՌΛຒΊࠐΉͳͲͷখࡉ޻͕ඞཁ

Slide 50

Slide 50 text

Kivy

Slide 51

Slide 51 text

Kivy • Φʔϓϯιʔεͷ 
 ϚϧνλονΞϓϦέʔγϣϯϑϨʔϜϫʔΫ • OpenGL ES 2.0ͱޓ׵ੑͷ͋Δ 
 άϥϑΟοΫඳըϥΠϒϥϦ • தؒݴޠKVͰͷը໘ɾ΢ΟδΣοτͷఆٛ • Android / iOS / Linux / Mac / WindowsʹରԠ

Slide 52

Slide 52 text

KivyʹΑΔΞϓϦέʔγϣϯ։ൃͷ͢͢Ί • PyCon JP 2017ͰͷJun Okazaki͞Μͷൃද • https://www.youtube.com/watch?v=iVOVpIXzbYY • https://www.slideshare.net/JunOkazaki1/pyconjp2017-kivy

Slide 53

Slide 53 text

KivyʹΑΔHello world from kivy.app import App from kivy.uix.button import Button class TestApp(App): def build(self): return Button(text='Hello World') TestApp().run()

Slide 54

Slide 54 text

Buildozer • KivyΞϓϦͷAndroid / iOS޲͚ͷύοέʔδϟʔ • Android޲͚ͷύοέʔδϯάͷࡍʹ͸ 
 Buildozer಺෦Ͱpython-for-androidΛར༻ • Ұ෦ͷPythonύοέʔδͷΠϯετʔϧʹ΋ରԠ • ඇରԠͷύοέʔδΛΠϯετʔϧ͢Δʹ͸ 
 recipeΛࣗྗͰ࡞੒͢Δඞཁ͕͋Δ

Slide 55

Slide 55 text

Plyer • OS΍୺຤ݻ༗ͷػೳΛ 
 Python͔Βར༻͢ΔͨΊͷAPI܈ • ৼಈ / Χϝϥ / GPS ... • ରԠ͍ͯ͠ͳ͍ϓϥοτϑΥʔϜͰ͸ 
 NotImplementedErrorΛraise͢Δ

Slide 56

Slide 56 text

Plyerͷαϯϓϧ from plyer import vibrator vibrator.vibrate(10)

Slide 57

Slide 57 text

Pyjnius • Python͔ΒJavaͷΫϥεʹ 
 ΞΫηε͢ΔͨΊͷϞδϡʔϧ • Plyer΋಺෦ͰPyjniusΛར༻͍ͯ͠Δ

Slide 58

Slide 58 text

Pyjniusͷαϯϓϧ from jnius import autoclass Context = autoclass('android.content.Context') PythonActivity = autoclass('org.kivy.android.PythonActivity') activity = PythonActivity.mActivity vibrator = activity.getSystemService(Context.VIBRATOR_SERVICE) vibrator.vibrate(10000)

Slide 59

Slide 59 text

Positive ! • ϑϨʔϜϫʔΫͷઃܭࢥ૝ͱͯ͠ 
 Ϛϧνλον͕ߟྀ͞Ε͍ͯΔ • OS͝ͱͷ෼ذ͕සग़͢Δ 
 ͳΜͪΌͬͯϚϧνϓϥοτϑΥʔϜͰ͸ͳ͍ 
 • ։ൃ͕׆ൃʹߦΘΕ͍ͯͯ҆৺ײ͕͋Δ

Slide 60

Slide 60 text

Negative $ • Flutter΍Jetpack Compose͕ଘࡏ͢Δ 
 ྩ࿨ͷ࣌୅ʹ͓͍ͯ͸ 
 UIͷͨΊʹผͷݴޠ͕ඞཁʹͳΔͷ͸ඍົ • ଞϑϨʔϜϫʔΫͱൺ΂Δͱ 
 ͢΂ͯʹ͓͍ͯϫϯςϯϙಈ࡞͕஗͍

Slide 61

Slide 61 text

Chaquopy

Slide 62

Slide 62 text

Chaquopy • ެࣜαΠτᐌ͘ “Python SDK for Android” • build.gradleʹهड़Λ௥Ճͯ͠ಋೖ • Java / Kotlinͷ୅ΘΓʹ 
 PythonͰ࣮૷͢ΔΠϝʔδ (ࠞࡏ΋Մೳ)

Slide 63

Slide 63 text

ChaquopyͰͷHello world from android.os import Bundle from android.support.v7.app import AppCompatActivity from java import jvoid, Override, static_proxy class MainActivity(static_proxy(AppCompatActivity)): @Override(jvoid, [Bundle]) def onCreate(self, state): AppCompatActivity.onCreate(self, state) self.setContentView(R.layout.activity_main)

Slide 64

Slide 64 text

ࠓԶ͕ॻ͍͍ͯΔͷ͸Java͚ͩͬʁ &

Slide 65

Slide 65 text

static_proxy • JavaͷclassΛҾ਺ͱͯ͠౉͠ 
 JavaͷιʔείʔυΛੜ੒͢Δ • Activity͸͜ͷϝιουͷ໭Γ஋Λܧঝ͢Δ • XMLͳͲίʔυҎ֎͔Β΋ࢀর͞ΕΔͨΊ 
 ͍ͬͨΜJavaʹ͢Δඞཁ͕͋ΔͱࢥΘΕΔ

Slide 66

Slide 66 text

static_proxyͷαϯϓϧ # <略> class MainActivity(static_proxy(AppCompatActivity)): # <略>

Slide 67

Slide 67 text

dynamic_proxy • JavaͷinterfaceΛҾ਺ͱͯ͠౉͠ 
 ࣮ߦ࣌ʹಈతʹJavaͷΫϥεΛੜ੒͢Δ • ಺෦Ͱ͸java.lang.reflect.ProxyΛར༻͍ͯ͠Δ • AndroidͰ͸interfaceΛଟ༻͢ΔͨΊ 
 ඇৗʹॏཁʹͳΔؔ਺

Slide 68

Slide 68 text

dynamic_proxyͷαϯϓϧ # <略> @Override(jvoid, [Bundle]) def onCreate(self, state): AppCompatActivity.onCreate(self, state) self.setContentView(R.layout.activity_main) class Listener(dynamic_proxy(View.OnClickListener)): def onClick(self, view): # クリック時の処理 self.findViewById(R.id.button).setOnClickListener(Listener())

Slide 69

Slide 69 text

Pythonύοέʔδͷಋೖ • ΞϓϦϨϕϧͷbuild.gradle಺ʹಋೖ͢ΔύοέʔδΛྻڍ͢Δ • ެࣜαΠτᐌ͘PyPIͷ্Ґ1000ύοέʔδத 
 88%͸ΠϯετʔϧՄೳ • ChaquopyͷαʔόʔͰҰ෦ύοέʔδͷwheelϑΝΠϧΛఏڙ • طଘͷAndroid޲͚ύοέʔδͰ͸࣮ݱෆՄೳͳػೳΛ 
 ఏڙ͢Δํ޲ʹৼΓ੾͍ͬͯΔҹ৅ (ݸਓͷײ૝Ͱ͢)

Slide 70

Slide 70 text

Android্Ͱಈ͘pandas from android.os import Bundle from android.support.v7.app import AppCompatActivity from java import jvoid, Override, static_proxy import pandas as pd class MainActivity(static_proxy(AppCompatActivity)): @Override(jvoid, [Bundle]) def onCreate(self, state): AppCompatActivity.onCreate(self, state) self.setContentView(R.layout.activity_main) url = "http://npb.jp/bis/players/81085115.html" df = pd.read_html(url)[1].query('年度 == 年度') Log.d("PyConJP", str(df['本塁打'].sum()))

Slide 71

Slide 71 text

ϥΠηϯεྉۚ • ΦʔϓϯιʔεͰͷར༻͸ແྉ • ΫϩʔζυιʔεͰͷར༻͸ 
 ։ൃऀ਺ʹԠͨ͡ϥΠηϯεܖ໿͕ඞཁ • 1ΞϓϦͷΈ༗ޮͳϥΠηϯε $39/ਓ • ΞϓϦ਺ແ੍ݶͷϥΠηϯε $79/ਓ

Slide 72

Slide 72 text

Positive ! • ಋೖ͕༰қ • Java / Pythonͷύοέʔδͱ࿈ܞ͕Մೳ • Java / KotlinʹΑΔΞϓϦ։ൃͷ஌ݟΛ 
 ΄΅ͦͷ··׆͔͢͜ͱ͕Ͱ͖Δ

Slide 73

Slide 73 text

Negative $ • ແྉͰ͸ͳ͍ • ϓϩΩγΛ௨ͨ͠Ϋϥεͷิ׬ʹਏΈ͕͋Δ • ·ΔͰJava΍KotlinΛॻ͍͍ͯΔؾ෼ʹͳΔ

Slide 74

Slide 74 text

͓·͚

Slide 75

Slide 75 text

੯͘͠΋બ֎ • BeeWare • PySide for Android

Slide 76

Slide 76 text

BeeWare • PythonʹΑΔΫϩεϓϥοτϑΥʔϜ։ൃ؀ڥ • Mac / Windows / Linux / iPhone / iPad / Android 
 AppleTV / tvOSʹରԠ • Android͸VOCͱͷ࿈ܞͰಈ࡞͢Δ • PythonόΠτίʔυΛJavaόΠτίʔυʹม׵

Slide 77

Slide 77 text

BeeWareબ֎ͷཧ༝ • Android Studio 3ܥͰಈ࡞͠ͳ͍ • Apple੡඼༏ઌͷํ਑Λެݴ͓ͯ͠Γ 
 ରԠ͞ΕΔ·Ͱ͕͔͔࣌ؒΓͦ͏

Slide 78

Slide 78 text

PySide for Android • PySide (QtͷPythonόΠϯσΟϯά) ʹΑΔ 
 AndroidΞϓϦ։ൃ؀ڥ • Qtͱ͍͏࣮੷ͷ͋ΔGUIϥΠϒϥϦΛ 
 AndroidͰར༻͢Δ͜ͱ͕Ͱ͖Δ

Slide 79

Slide 79 text

PySide for Androidબ֎ͷཧ༝ • Android্Ͱಈ͔ͤ·ͤΜͰͨ͠…… • ΋͠஌ݟΛ͓࣋ͪͷํ͕͍Βͬ͠ΌͬͨΒ 
 ΞυόΠεΛ͍͚ͨͩΔͱ޾͍Ͱ͢

Slide 80

Slide 80 text

·ͱΊ

Slide 81

Slide 81 text

React Native + Transcrypt • ࣮੷ͷ͋ΔReact Nativeʹ৐͔ͬΔ͜ͱ͕Ͱ͖Δ • React NativeΛૉͷJavaScriptͰ 
 ॻ͍͍ͯΔͷͰ͋Ε͹࠾༻ͯ͠΋ྑ͍͔΋ • ࢒೦ͳ͕ΒTypeScript౳ͷ༗ྗͳAltJSΛ 
 ஔ͖׵͑Δ΄ͲͷΠϯύΫτ͸……

Slide 82

Slide 82 text

Kivy • ଞݴޠʹҾ͖ͣΒΕΔ͜ͱͷͳ͍ 
 PythonicͳAndroid։ൃ͕Ͱ͖Δ • ։ൃ͕׆ൃͰࠓޙʹظ଴͕࣋ͯΔ • Androidʹؔͯ͠͸ 
 ୺຤ͷεϖοΫ͕௥͍͍͍ͭͯͳ͍͔΋

Slide 83

Slide 83 text

Chaquopy • ࣮༻ੑͰ͸τοϓΫϥε • طଘͷAndroid։ൃͷ஌ࣝΛ 
 ͦͷ··׆͔ͤΔͷ͸େ͖͍ • ϥΠηϯεྉ͕ۚ໰୊ʹͳΒͳ͚Ε͹ 
 ༗ྗͳબ୒ࢶʹͳΔ͸ͣ

Slide 84

Slide 84 text

࠷ޙʹ • ʮPythonͰAndroidΞϓϦ։ൃ͸ݫ͍͠ʯ 
 ͱ͍͏݁࿦ʹ͢Δͭ΋ΓͰCfPΛఏग़͕ͨ͠ 
 ͍͍ҙຯͰཪ੾ΒΕͨ • Android Studio͸αΠζ͕େ͖͍ͷͰ 
 ձ৔ͷWi-FiͰ͸μ΢ϯϩʔυ͠ͳ͍ͰͶʂ

Slide 85

Slide 85 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠