มางาน Mobile Conf 2019 อย่างงอยเหงา
เหงาเพราะไม่มีทีม dev เราไปงานนี้เลย (ปีที่แล้วยังอุตส่าห์เป็นสปอนเซอร์นะ) ฮืออออ เจอแต่คนหน้าไม่คุ้นล่วยย ตอนเย็นไปกินเป็ดปักกิ่งงานแต่งเพื่อนด้วยหล่ะ เอ๊ะเหมือนอวด555
ปล. ทางเราจะมีอัพเดตเรื่อยๆเกี่ยวกับ silde ของ speaker และวิดีโอย้อนหลัง อย่างน้อยเราก็เก็บไว้ดูเอง555
ปีที่แล้วงานเขาจัดครั้งแรกเนอะ แล้วเราไม่ได้ไป ติดธุระที่บ้าน เลยมาลองสัมผัสในปีนี้จ้า
ปีนี้จัดวันเสาร์ที่ 25 สิงหาคม ที่โรงแรม S31 คุ้นๆเนอะ ที่เดียวกับงาน Android Bangkok ไงหล่ะ session มีความหลากหลาย แค่ตอนเช้า Flutter, Security, Chatbot เลยนะ
ตอนเช้ามี swag ของงานมาให้เราสะสมด้วยหล่ะ
แล้วมีชากาแฟบริการกันตลอดวัน ดีงามอ่ะ
Opening Remark
เมื่อถึงเวลา มี MC สาวสวยสองท่านจ้า มีท่านนึงคนผมดำเป็นสาวไต้หวัน ดินแดนแห่งชานมไข่มุก (และนักวาดที่เราชอบคือวานวาน ก็เป็นคนไต้หวันด้วยน้าาา)
คร่าวๆบรีฟเรื่องชากาแฟ ห้องนํ้า ปั้มที่จอดรถ และโพสเกี่ยวกับงานผ่าน hashtag #mobconf19 จ้า
How Kotlin Met Flutter — Travis P Subannaphong
เราพบว่า session ที่เป็น Flutter ทีไร เปิดโลกเราตลอดดด ส่วนทางเราจะลองแต่ก็ยังไม่ได้ลองเจ้า Flutter ซะที
Flutter คืออัลไล เราก็ทราบคร่าวๆเนอะ ว่าเป็นสิ่งที่เขียนทีเดียว ใช้ได้ทั้ง web, iOS และ Android สามารถเนรมิตได้ด้วยภาษา Dart
แน่นอนตัวโค้ดนั้น ง่ายกว่าการเขียนแอปแอนดรอยด์อีก ง่ายกว่าตรงไหน ตรง UI ไง มันเป็น widget เช่นอยากได้ app bar ใช่ไหม เอาไปแปะในโค้ดเลย อยากได้ floating action button ก็ใส่ไป อยากได้ล่างขวา เราสามารถเพิ่ม attribute ได้ด้วยว่าไปอยู่ตรงนั้นนะ ใส่ในโค้ดปุ๊ป ได้ view ออกมา ไม่ต้องทำไฟล์ layout แยก อยากให้เปลี่ยนสี text ก็ไปใส่เพิ่มที่ widget text ว่าชั้นจะเปลี่ยนเป็นสีแดง อะไรแบบนี้
ซึ่งจะมีการเปรียบเทียบระหว่าง iOS Android และ Flutter เป็นระยะ เพื่อให้เราเข้าใจกันมากขึ้นเนอะ
พวก scrollable นั้น Flutter มีก้อนเดียวเลยงี้ ก็คือเจ้าพวก RecyclerView ที่รักของชาวดอยหล่ะ หรือ Cell ของ iOS Dev ใส่ทีเดียวว่าตรงไหนคืออะไร จบปิ้งจ้า รันได้เลย ว๊าวสุด
ส่วน custom view ก็เช่นกัน ระบุทีเดียวจบเลยใน Flutter มาเทียบกับฝั่งดอยคือเราทำทำไมเยอะแยะให้เหนื่อยกันนะ
แล้วในกรณีเปิดหน้าอื่นและกลับเจ้ามาใหม่หล่ะ ใน demo นี้ คือ เปลี่ยนชื่อ user จาก kotlin เป็นชื่อ github ของ speaker ค่าหลังจากกลับมาก็เป็น github ช่ือ user ที่กรอกไปเมื่อกี้เนอะ โดยการดึง data มาจาก API ซึ่งในมุม Flutter มีความซับซ้อนน้อยกว่า
ถ้าอยากจะทำ Flutter ต้องเขียนแอปที่มีอยู่ใหม่หมดเลยใช่ไหม ไม่ต้องจ้า สามารถ integrate เป็น Flutter ได้เลย ตาม platform
แต่ Dart มันไม่ดีตรงไหน ตามรูปเลยจ้า ซึ่งในทีมก็เห็นด้วยเช่นกันจ้า
ดังนั้น ตรง UI นั้นใช้ dart ส่วน business logic ก็ภาษาตาม platform เนอะ
และใช้ Kotlin multiplatform และเป็นแบบ MVVM แล้วก็ใช้ delegate ฝั่ง iOS และ Coroutine ฝั่ง android ด้วย
ซึ่งได้รับการ approve และใช้บน production จริงด้วยจ้า
ช่วงถามตอบ เราจะจดแบบขี้เกียจในทุก session เนอะ
- debug code ฝั่ง dart กับ kotlin ยังไง ซึ่งสามารถ debug code ได้ตามปกติ ซึ่งทำได้ทั้ง Android Studio และ Intellij
- UI สามารถ copy design จากฝั่ง web ให้เป็น native ได้
สุดท้ายทาง speaker ได้ฝากมาดังนี้จ้า
source code ใน github ลองเล่นกันดูได้
ส่วนอันนี้เอาไปอ่านกันดูจ้า
ส่วนอันนี้ publishion ใน medium ที่เกี่ยวกับ Kotlin และ Android
เราถ่ายรูปมาอาจจะอ่านแบบงงๆ ไปดูสไลด์ย้อนหลังกันได้เลยจ้า
Mobile Defense-in-Dev(Depth) (Thai) — Prathan Phongthiproek
ปีก่อนเขามี session ในมุม hack ปีนี้ในมุม defense
dev app zero to hero and no security, good luck
ใน session นี้เขาจะเปิดภาพกว้างๆมาก่อน แล้วเจาะรายละเอียดในสไลด์หน้านั้นจ้า
ตอนแรกเขาจะฉายภาพให้ดูคร่าวๆ ว่าเราในฐานะ mobile developer ควรระวังการ attrack จากอะไรบ้าง เช่น การกรอก input, deeplink, database, data storage, binary, reverse enginerring (แปลงแอปของเราออกมาเป็น source code สามารถ analyse การเขียนของแอปนั้นๆ และเปลี่ยนการทำงานได้), hardcode ถูกแปลงเป็น binary ได้, ป้องกันเรื่อง root และ jailbreak, SSL, backend side, API business logic
defense in depth เปรียบดังค่ายทหาร ที่อุดรูรั่วไม่ให้ข้าศึกเข้ามา
standard ของ session ในวันนี้ ก็คือ MASVS ฟรีและมี checklist ในการ protect ด้วย แบ่งเป็น level L1 L2 R ตาม industy ของแอปนั้นๆ
และแบ่งเป็นข้อๆ มี 8 ข้อ ดังนี้
ปล. ทั้งหมดสามารถเข้าไปอ่านได้ที่
V1 Architecture, Design and Thread Modeling
- เอา security ในการใช้ dev lifecycler ในทุกจุด และแน่นอนต้องทำ pentest ด้วย ซึ่งจะ concern security ตรง testing ถ้าเจอ issue หลักๆจากเด้งกลับไป process develop เสียหายหลักสิบล้าน และเสียเวลาแก้ใหม่เป็นเดือน
- ถ้าเก็บ data ในเครื่อง เก็บอย่างไร และ hack ยากไหม
V2 Data Storage and Privacy
- 3 ใน 4 ของ Android app มักเก็บข้อมูลสำคัญ เช่น username, เบอร์โทร ต่างๆ ซึ่งไม่ควรเก็บไว้ในเครื่อง ควร check กับ gateway เจอในแอป shopping online
- ควรเก็บ data ไว้ในฝั่ง server พวกเกมส์สามารถเอาไป modify และเอาไป hack ต่อได้
- ตรวจสอบ 3rd-party library ว่าเก็บข้อมูลเกินควรจำเป็นหรือไม่ และไม่ควรเชื่อถือว่า library ใน github ที่มีดาวเยอะๆ จะปลอดภัยนะ และถ้าโดน hack ก็จะโดนกันเยอะเลย
- สำหรับชาว Android สามารถ set
backupFlag=false
ใน AndroidManifest เพื่อไม่ให้ backup ข้อมูลได้
ตัวอย่างที่ยกมาในข้อนี้คือ เครื่องกดนํ้า ในเคสนี้ password คือ getDeviceId ก็คือค่า IMEI ของเครื่องนั่นเอง ผลคือเอาไปซื้อนํ้าจากตู้น้ำโดยเติมเงินจริงไป 5$ แล้วซื้อน้ำจากนั้นเปิดแอปที่ทำการ Reverses Engineering มาแล้ว และเปิดกลับเข้าออกจริง เงินที่เติมไปก็ recover กลับมาหมด เท่ากับว่าซื้อนํ้าจากตู้ฟรีเลย
อ่านกันต่อได้ที่นี่
V3 Cryptography
- Code ที่เราชอบไปก้อปแปะใน Stackoverflow อาจจะมีช่องโหว่ได้นะ
- ควรใช้ security random มากกว่า
Math.random()
ที่มันสามารถ predict ได้
V4 Authentication and Session Management
- Case study ที่หยิบยกมาคือของ Grab และ 3fun ซึ่งความน่ากลัวคือเก็บ real-time gps ตลอดเวลา และตัว API มันคาย data ออกมาเยอะเกินความจำเป็น
- JWT นั้นมีปัญหาเยอะ สามารถ modify ค่าใน token ได้ (ส่วนตัวเคยเห็นเว็บที่ decode ตัว token ออกมาเพื่อดู data ได้) และบางออกไม่มี refresh token ด้วย (เฮ้ย)
- ควรใช้ keystore ในการช่วยดึงร่วมด้วย
V5 Network Communication
- ใช้แอปดัก proxy ขาไปและกลับได้
- End-to-end เรียกผ่านหลังบ้านและไม่ให้ดักตรงกลางได้
V6 Environmental Interaction
- Permission อย่าใช้เยอะเกินความจำเป็น ถ้า library อะไรที่ขอเกินหน้าที่ก็ต้องระวังเนอะ
V7 Code Quality and Build Setting
- Real-time Database ดักมีคนเก็บ plain text password และ userId ไว้ในนั้น ซึ่งก็เคยมีข่าวว่ามี data หลุดออกมา เพราะ security rule ดันเป็น true หมดบน production จะคล้ายๆเคส S3 ซึ่งลองใส่ /.json หลัง url ของ database แล้ว ได้ data ออกมาทั้งหมด
- ตัวอย่างแอปที่โดนผลกระทบ เช่น Booster ดันได้ data ของคนอื่นออกมาด้วย
- อีกเคสนึงคือ ช่องโหว่ใน Facetime ประมาณว่าปลายทางไม่ได้รับสาย แต่ต้นทางดักฟังได้เง้
V8 Resiliency Against Reverse Engineering
- ช่วยป้องกันการ reverse engineering
- Proguard ไม่ได้ช่วยให้ปลอดภัยเสมอไป
- Signed แปลงออกมาเป็นตัวที่อ่านยากๆเรียกว่าอะไรสักอย่างจำไม่ได้แล้ว ฮือออ
- In-app purchase มีการส่ง billing ไปมา proxy app คาย state ทุกครั้งที่ซื้อ สามารถใช้แอปเหล่านี้ทดลองได้
สรุปทำไปแล้วก็ไม่ได้ปลอดภัยหายห่วงทั้งหมด แต่ๆๆๆเราควรต้องทำเพื่อ bypass ยากขึ้น
Conversation Design in LINE Business Connect (Thai) — Pornpat Pimjaroen
รู้สึกแปลกใจกับ session นี้พอสมควร เพราะเป็น session chatbot ในงาน mobile dev นี่แหละ ฮ่าๆ (จริงๆคือแอบโดดจาก session อื่นๆที่เป็น mobile developement)
Session นี้เป็นการรวมร่างของ UX กับ dev เพื่อทำ LINE Business connect ก็คือ chatbot ที่โต้ตอบกับลูกค้า ในที่นี้คือทำ chatbot ของธนาคารแห่งหนึ่ง
UX คืออะไรกันนะ ตัวอย่างก็คือลูกของคุณนิ้ง ที่เล่นในอ่างอาบนํ้าเล็กๆของเด็ก มีของเล่น แต่ไม่มีนํ้าเลย แต่น้องเขามีความสุขมากๆ ดังนั้น
UX คือคนที่ให้ความสำคัญกับประสบการณ์ที่มีความสุข ไม่ใช่ product
ในที่นี้มอง product เป็นนํ้าในอ่างนะ
การ conversation เริ่มจากคนเดินไปคุยกัน ไปเป็น กลายเป็นคุยผ่าน social network กันมากขึ้น
Business Problem คือป้าไม่กล้าลงแอปธนาคาร และไม่มีเวลาไปที่สาขาด้วย ส่องแอปในเครื่องป้าแน่นอนว่าจะเหมือนกับพ่อแม่ที่บ้านเรา ก็คือ Facebook, LINE, YouTube ก็เลยเลือกมาทำ chatbot ใน LINE
ซึ่งเจ้า chatbot ใน LINE จะช่วย solveในการตอบคำถามซํ้าๆ เช่น check ยอดเงิน, อายัดบัตร, บัตรหาย, ตู้ ATM ที่ใกล้ที่สุด, ตู้ ATM กินบัตร และถ้าทุกคนโทรหา call center ก็จะรอสายนานมากก และต้องการเรื่อง personal promotion รายคน ให้โทรหาเราคงบล็อกเบอร์ไปก่อน เอ้ยยย คนโทรเหนื่อยไปซะก่อนที่จะโทรหมดทุกคน
ตอนแรกเอา FAQ มาตอบ เลยทำให้ user มี experiences ที่ไม่ดี เนื่องจากตอบเป็นทางการเกินไป (เราคิดว่าอาจจะดูสำนวนภาษาแข็งไป ไม่เหมือนคุยกับคนด้วยแหละมั้ง)
ทำ chatbot persona ขึ้นมา ชื่อน้องแกงส้ม พอได้คาแรคเตอร์เสร็จแล้วปุ๊ปพาน้องแกงไปเรียน ต้องตอบสวัสดี user ให้เป็น
ส่วนคำถามที่จะเทรน ไปถาม call center ว่ามีคำถามอะไรถามบอทบ้าง (เรางงๆตรงนี้นะเอาจริงๆ เราจดตามที่เขาพูดแบบนี้ง่ะ) พอพาน้องแกงไปเรียนเสร็จปุ๊บ ไปทำงาน user บอกว่าตอบคำถามเขาไม่ค่อยได้
วิธีแก้ของทีมนี้คือให้ user ไปามในสิ่งที่เราต้องการให้ถาม และมีท่าไหนบ้างหล่ะ มี Imagemap อย่างของคนอร์คือเก็บข้อมูลจากที่ user กดไปส่งหลังบ้าน แล้วทุกเช้าระบบหลังบ้านจะส่งรูปอาหารเช้าใน type ที่เราเลือกกลับไป, Rich menu, Carousel ซึ่งทางเราขอข้ามรายละเอียดไป เอาจริงๆคือมันเป็นแบบง่ายๆไม่คิดไรมากนะ แล้วเขาบอกประมาณว่าในไลน์มีหน้าตามาให้แค่นี้ หื้มเลยยยย ลืม Flex Message หรือเปล่านะ อันนั้นมันปรับได้ตามใจ เราเองก็เคยลองเคยเห็นอยู่นะ
สุดท้ายจ้า เขาเปิด LINE bot designer และทำให้ดูแบบคร่าวๆทั้ง Imagemap และ Flex Message จ้าา เบาใจหน่อยทางนี้นึกว่าเขาลืมไปแล้ว555
ทุกวันที่ 16 และวันที่ 30 นั้น มีการขอหวยจากบอทด้วยนะเออ 555
มื้อกลางวันเป็นบุฟเฟ่ต์ของโรงแรม ลงไปทานชั้นล่างจ้า
ตอนนั้นได้ข่าวจากเพื่อนที่เป็นเจ้าบ่าวว่าที่งานแต่งมีเป็ดปักกิ่งด้วย รอเลยฮะ ณ จุดนี้
มาช่วงบ่าย กับการเปลี่ยนห้องเพื่อเป็นการออกกำลังกาย และเราเข้าทุก session ที่เป็น Android ทั้งหมดเลย เราเดาถูกเว้ย 555
Modularization transformation (Thai) — Jeeraphan Lairat
เป็น session ที่ดีแพ็คคู่กับอันต่อมา คือเนื้อหาดีมากๆ เอาไปปรับใช้ในทีมได้เลย
การเดินทางของ product ก็เหมือนคนที่ขี่จักรยานไปไหนสักที่ มีสัมภาระด้านหลัง พอเวลาผ่านไป ผ่านไป สัมภาระข้างหลังก็เยอะขึ้นๆ ความคล่องตัวของเราก็น้อยลง เลยทำให้ขี่จักรยานได้ช้าลง นั่นคือเราทำงานได้ช้าลงนั่นเอง
ปัญหาเหล่านี้เกิดจากอะไรหล่ะ เกิดจากคน แล้วหลักๆคือ build time ซึ่งเวลา build app ต่อครั้งโดยเฉลี่ยตกอยู่ที่ 6 นาที (ส่วนของเรา build apk ลงเครื่องอย่างมากไม่เกิน 2 นาที ส่วน build bundle ลงเครื่องก็ประมาณ 5–6 นาทีซึ่งนานมากๆเลยนะ) สมมุติ build ไป 10 รอบ คือ 6 นาที x 10 รอบ = 60 นาที = 1 ชั่วโมง เลยนะ
แล้ว Modular Architecture คืออะไรกันนะ?
ก่อนอื่นเรามารู้จัก Single Module คืออะไร ก็คือโปรเจก Android ที่มี module นามว่า app เพียง module เดียว ถึงทีมจะมีหลายคน แบ่งหลาย feature ทุกคนรุมไปทำที่เดียว ทำให้โค้ดเกิดการ confilct และอาจจะไม่ทันส่งงาน เพราะอาจจะนั่งแก้ นั่ง build ใหม่ก่อนส่ง (ส่วนของเรามีหลาย module แต่ดันรุมที่ app module ที่เดียว ตึ๋งโป๊ะ)
ดังนั้นเปลี่ยน 1 feature ก็ต้อง build ใหม่ทั้งหมด โอ้วเยโอ้เย้
เริ่มทำกันเถอะ~ มาดูกันก่อนว่าแอปนี้มี feature อะไรบ้างนะ ในที่นี้มี coin, coupon, network เนอะ
แยก feature ออกมาเป็น module ต่างๆ โดย apply plugin: ‘com.android.library’
ซึ่ง module app นั้นจะเห็น module library ต่างๆ แต่ module น้อยๆที่เพิ่งแยกมาจะไม่เห็น module app เนอะ ซึ่งก็สมเหตุสมผลในแบบของมัน
module แรกผ่านไป …. (เริ่มมีเสียงฮามาหล่ะ สักพักมีคนพูด ไฟไหม้สบง 555) เริ่มแยกมาตัวอื่นออกเป็น module มาเรื่อยๆ แต่จะเริ่มเจอปัญหา คือ app ใช้ class A จาก module หนึ่ง และแน่นอนว่าเรียกใช้ class A แล้วยังไม่จบแล้วจบเลย มันจะเรียกพวก class อื่นๆมา ทำให้ติดปัญหาขึ้นมา
ตอนแรกว่าจะเลิก way นี้ไปแล้ว แต่สุดท้ายก็ start again จ้า ย้ายตัว code base ต่างๆที่ต้องใช้ไว้ใน core แล้วค่อยๆ move มา แบบนี้ ดังนั้นจึง solve ปัญหานั้นได้แล้ว แน่นอนว่าตัว core คือเป็น code ก้อนที่นิ่งที่สุด คือมีการเปลี่ยนแปลงโค้ดน้อยที่สุดในแอป
แล้วมันทำงานเร็วขึ้นยังไงง่ะ?
สมมุติ module coin มีการแก้โค้ด การ compile จะไป compile ก้อนที่เปลี่ยน คือ compile :coin แล้วก็ :app ไม่ได้ compile ทั้งหมด เลยทำให้ไวขึ้นกว่าเดิมจ้า ซึ่งจริงๆเขามี result ให้ดูเลยว่าใช้เวลาเท่าไหร่ แต่เราไม่ได้ถ่ายรูปมาจ้า
Declaring Dependencies
build.gradle เวลาเรา import dependency ต่างๆ จะใช้ api กับ implement แล้วต่างกันยังไงอ่ะ
Navigation
จากเดิมที่เรา intent Activity ต่อไป จะเปลี่ยนเป็นไป set ที่ AndroidManifest แทน
ใน fragment ก็ทำได้เหมือนกันนะ …
Scale
สามารถแบ่งทีมรับผิดชอบในแต่ละ module ได้
Flexible
แต่ละ module สามารถใช้คนละ pattern ได้ ตามใจชอบ ไม่ทะเลาะกัน ถ้าอยากใช้แบบใหม่ๆก็อาจจะใช้แค่อันเดียวไปก่อนงี้
สรุปจ้า
- build ได้เร็วขึ้น แต่ขึ้นอยู่กับ spec คอมของ dev ด้วยเน้อ
- ได้ลองอะไรใหม่ๆ
- reuse module ไปแอปอื่นๆได้ถ้าเขาจะใช้ ลด cost ไม่ต้องมาทำใหม่หรือก้อปโค้ด
- สามารถต่อยอดเพิ่มได้ เช่นทำ Android App Bundle
ช่วงถามตอบ จดได้เท่าที่ไหว55
- ปัญหาในการแยก module ในตอนนั้นคืออะไร คือการไปขอ effort PM และ QA เพื่อทำ Unit Test หลังจากการแยก module มีการตกลงในทีมการจัดโค้ด การ duplicate code
- ใช้เวลาแยกที่เล่าให้ฟังใน session นี้สัก 10 วัน เพราะติดเรื่อง class A ด้วย
- ยังไม่ได้ลงใช้เจ้า Single Activity เลย
- ถ้าเอาให้แอปอื่นไปใช้สัก module นึง สามารถดึงจาก repo module ตรงๆได้เลย (เดี๋ยวไปลองดู)
สไลด์ speaker จ้า
Cut your APK size with features on demand — Suneet Agrawal
เป็น session ที่ดีต่อจากอันข้างบนมา เป็นการขยายความในส่วน dynamic feature ด้วย
คุณมีปัญหาแอปพลิเคชั่นแอนดรอยด์ที่อ้วนอยู่ใช่ไหมครับ จน Play Store ถาม user ว่า download แอปผ่าน WiFi ไหม หรือมีพื้นที่ใน device user ไม่พอ ซึ่งแน่นอน user concern เกี่ยงกับขนาดของแอปถึง 70% เลยทีเดียว
เมื่อทุกๆ 6 MB ของขนาดแอปเรา มันคือ conversion rate 1% ที่มีผลกระทบ แล้วอะไรคือสิ่งที่เราควรทำหล่ะ?
แอปตัวอย่างในที่นี้คือ ShareChat Camera ซึ่งมีกล้อง filter/sticker และ FFMPEG
ซึ่งเริ่มหนักที่ FFMPEG แล้วนะ และมี filter sticker และผองเพื่อน 3rd-party library ก็จะยิ่งบวมมากขึ้น
Android App Bundle ช่วยคุณได้
จริงๆก็เพิ่งออกมาไม่นานมาก ช่วยแก้ปัญหาเรื่องแอปที่มีขนาดใหญ่ ให้มีขนาดที่เล็กลง
ซึ่งมันจะ spilt พวก language, densities หน้าจอ และ ABIs จาก APK เพื่อส่งไปให้เหมาะสมในแต่ละ device
แล้วเราจะทำมันได้อย่างไรหล่ะ ทำดังนี้จ้า บางทีเราก็ถ่ายมาไม่ชัดเนอะ
อธิบายคร่าวๆ ใน build.gradle นั้น ใส่แบบนี้ไปเพื่อ spilt ของพวกนี้ออกเพื่อสามารถใส่ไปให้เหมาะสมในแต่ละ device เนอะ ซึ่งถ้าอยาก spilt ก็ใส่ true ไป
ไม่เพียงแค่นั้น สามารถ set แบบละเอียดได้ด้วยว่าจะแบ่งยังไง ในที่นี้จะแบ่งส่วน ABI งี้ บางไฟล์ที่เป็น native C++ หรือ ไฟล์ .so App Bundle จะช่วยทำให้เบาลงได้ด้วย
ปล. เราเองจะมีบล็อกเกี่ยวกับ Android App Bundle ให้อ่านกันนะ รอตรวจแปป
พวก filter sticker เป็น Dynamic Feature เนอะ ดังนั้นทำเป็น module แยก แล้ว Dynamic Delivery คืออะไรกันนะ? คือเป็นการหยิบส่วนที่ spilt ออกมา ใส่ให้เหมาะสมกับ device นั้นๆ และการทำงานในส่วนนี้คือ download feature นั้นๆมา install เมื่อตอนที่เราจะใช้มัน
การสร้าง เลือก Dynamic Feature Module ใน Android Studio เนอะ
และสามารถ เลือกได้ว่าเราจะ install-time inclusion แบบไหน มีแบบจะใช้ค่อย install, install เลย กับอีกอันยังงงๆอยู่ แหะๆ และใส่ชื่อ title ให้ user เห็นด้วยว่าสิ่งนี้คืออะไร
สิ่งที่เกิดขึ้นก็คือ ที่เราเพิ่งสร้างไปจะถูกใส่ใน build.gradle และ AndroidManifest แล้วก็ถูก implement เพิ่มในโค้ด ตอนจะเรียกใช้ และ handle ในแต่ละ case ด้วยใน listener
พอทำเสร็จก็จะเป็นแบบนี้ แบบนี้
เปรียบเทียบกับ instant App สักหน่อย ต่างกันไหม ต่างสิ ต่างเยอะด้วย เพราะ instant app เหมือนเราสร้าง module นึงเพื่อให้ user มาลองเล่น ไม่ใช่แอปจริง มีขนาดไม่เกิน 15 MB ถ้าอยากใช้แบบเต็มๆก็ download แอปจริงมาลง ส่วน dynamic delivery นั้นก็คือ module ที่มี base เป็นแอปที่เราลงนี่แหละ
ข้อควรระวัง สามารถใช้ได้ตั้งแต่ API Level 21 ขึ้นไป นอกนั้นไม่ support on demand module นะเออ กับอีกข้อนึงอ่านเอานะ ฮ่าๆ
ฝากร้านก่อนจบ session จ้า ชอบการให้ Google search ชื่ออ่ะ
Architecture Components in Real Life - Season 2 (Thai) — Somkiat Khitwongwattana
season แรกผ่านไป …….. season สองก็มาสิค๊าบบ (เลิกต่อมุขไปไหม้สงบได้แล้วนะ) เหตุเกิดคือมาขยายความจากปีก่อนนี่แหละจ้า
ปีก่อนพูดถึงสี่ตัวนี้คือ Lifecycles, LiveData, ViewModel, Room ซึ่งตัวข้างล่างก็มาเพิ่มนะ แต่ยังไม่ได้พูดถึงนะ
Use Case ViewModel :Dialog Event Listener
ใช้ DialogFragment ในการสร้าง Dialog เนอะ ถ้ากด OK ไปแล้วก็ไม่มีอะไรหรอกนะ แต่เมื่อเกิด config change เท่านั้นแหละ listener ถูกทำลายหายไป ดังนั้นพอกดแล้วมันจะเฉยๆไม่มีอะไรเกิดขึ้น
ดังนั้นจึงเอาไปฝากไว้ที่ ViewModel แทน และควรใช้ LiveData เพื่อ performance ที่ดีที่สุด พอเปลี่ยนแล้วส่วนอื่นๆในโค้ดต้องเปลี่ยนตาม เลยใช้ Mapper ครอบไว้
ตัวอย่าง เก็บ key ใน LiveData ซึ่งเจ้า key ที่ว่าก็คือ event ที่เกิดขึ้นคืออะไร จากนั้นเจ้า Mapper ก็จะแปลง LiveData กลับไปเป็น listener
MVVM + Clean Architecture
ซึ่งพอรวมร่างกันแล้วมันจะเอื้อต่อโปรเจก Architecture Components (ที่เราเคยเขียนบล็อกแต่ไม่เคยใช้เลย แง)
เอ้อ ทำไมต้อง MVVM หล่ะ? เราสามารถเขียน test ได้ และเขียนโค้ดกับคนอื่นในทีมได้
ปีที่แล้วที่เป็น season 1 อ่ะ มีคนลองเขียนตาม แต่ก็จะงงๆหน่อย ตรง business logic ถ้าไม่มี use case ทำใน ViewModel หล่ะ
เอา use case มาคั่นเพื่อเอา business logic เป็น domain layer ว่าให้ view แสดงผลอย่างไร
business logic หน้า login เอา use case มาคั่น เพื่อเอา login, ขอ token, ดึง profile ดังนั้นจะไม่ได้อยู่ใน ViewModel แล้วหล่ะนะ และคุยกันผ่าน LiveData เท่านั้น (Observer) ซึ่งเริ่มใช้ใน Google I/O 2018 แล้วนะ ซึ่งพวก level ที่ตํ่ากว่า ViewModel เขาก็จะยังไม่ได้ประกาศอะไรขนาดนั้น
การใช้เจ้า Use Case
แบบ synchronous แบบง่ายๆ UseCase<String?, Boolean>
ตัว input คือ String? และ output คือ Boolean จากนั้นเข้ามาทำ execute
ส่วนแบบ asynchronous ก็เป็นในลักษณะเดียวกัน แต่หลังจาก execute post value กลับไปเป็น LiveData ซึ่งจริงๆการเรียกเป็น synchronous หลัง execute ก็เป็น LiveData อยู่แล้วนะ
แล้วการเขียน test หล่ะ สามารถเขียนได้ง่ายขึ้น แต่ใช้ injection เพื่อ mock dependency ช่วยทำให้เขียน test ได้ง่ายขึ้น
ด้วย pattern สามารถแบ่งได้ตาม layer ได้ง่ายกว่าแบ่งแบบ by feature แบบ A ทำ UI ส่วน B ทำ use case ทำให้ส่งงานทัน และพอแบ่งเป็นส่วนๆ เอาไปทำก่อนได้เลย พอ merge งานก็ทำ type ให้ตรงกัน
ถ้าไม่ซับซ้อนนักก็ใช้ paging ได้เลย มันครอบทั้งหมด
ถ้าจะใช้ควรทำ POC (Proof of Concept) เอาอันเก่าๆที่เคยทำมาลองทำก่อน และดูว่ามัน work ไหม
เขาบอกว่า
ไม่ใช่วิธีที่ดีที่สุด แต่เป็นวิธีที่ flexible ที่สุด
ปล. ปีหน้าอาจจะมี season 3 จ้า
ช่วงถามตอบ
- การใช้ LiveData กับ Repo ขึ้นอยู่กับ business logic และการ handle
- use case เรียกกันเองได้ไหม ไม่ผ่านคนอื่น อันนี้พี่เอกกำลังลองทำ experiment อยู่จ้า
เพิ่มสไลด์พี่เอกแปป
Diving into coroutines — Enrique López Mañas
session นี้พูดเกี่ยวกับโค้ดเยอะมาก เกี่ยวกับ Coroutine นั่นแหละ เข้าใจว่าเราควรเข้าใจ concept ของมันก่อน ประมาณนั้น ด้วยความที่เราเองฟังและดูสไลด์ เลยไม่ค่อยได้จดเท่าไหร่จ้า บางที speaker แอบมีงึมงำด้วย แบบงงๆเขาพูดอะไรน้าาา
คร่าวๆคือแยกการทำงานออกมาจาก Thread หลัก
และนี่ครืออออ สาเหตุที่ต้องใช้ Coroutine
มีการเปรียบเทียบมั้ง ระหว่าง RxJava LiveData และ Coroutine ซึ่งเจ้า Coroutine ทำงานแบบ asynchronous
ซึ่งเขาก็ได้อธิบายการทำงานของโค้ดว่าอยู่ใน Thread แล้วเป็นประมาณไหน
และก็พูดถึงวิดีโอนี้ด้วย
อันอื่นๆไม่ได้จดง่ะ
Building Block
สามารถรัน 2 tasks พร้อมกันได้ และสามารถ cencel ได้
จัดการ error handing พวก try-catch
ผลการ survey ส่วนใหญ่คือ Coroutine คืออิหยังวะ
ส่วน resource ต่างๆที่เอาไปอ่านหรือทำเพิ่มเติม
Letter to designer and product manager — Jason Nam (남석현)
Session สุดท้ายแล้ว ฟังจบยังแอบงงเพราะ speaker เป็น iOS Developer แล้วเราไม่ค่อยเก็ทเท่าไหร่ ฮ่าๆ
ตอนเปิดเรื่องมาเป็นเรื่องเป็นราวดี แต่หลังจากนั้นแอบงงง
ประเด็นที่เขาพูดมี 2 ประเด็นคือ
1. It is more sophisticated than it looks like
- Typography : dynamic type ต่างๆ เช่น fonts size ต่างๆ
- design doc ฝั่ง iOS พูดถึง good UX, input hardware support, system level feature
- The concept of app is more sophisticated than it looks like
- พูดถึง Steve Job ถึง history ของ iPhone ที่ออกมาเปลี่ยนโลก ในคอนเซปออกนอกกรอบ เป็นมือถือที่ต่อ internet ได้ แต่เหมือนเขาก็แซวว่าพอเวลาผ่านไปก็ติดกรอบ edge อยู่ดี (ไม่แน่ใจว่ากล่าวถึง NavigationBar หรือเปล่า มันก็คือ Gesture Navigation ฝั่งดอย) ตึ๋งโป๊ะ ตัว feature ที่ออกนอกกรอบก็จะมี widget, iMessage, custom notification, Siri UI, home screen action
- แต่ความดราม่าคือการนำ iPad app มาอยู่บน mac
- แล้วก็ไม่ clear การแบ่งขอบเขตของแต่ละตัวด้วยนะ
2. Mobile apps are not photos but movies
- usually 1 design
- มี dimension ขนาดเดียว และ design เป็น responsive
- essential information
- แล้วพวก information ควรใส่อย่างไรหล่ะ
- และทำอย่างไรให้ UI Support multiple platform ทั้ง iOS และ Android ดังนั้นต้องรู้ก่อนว่ามีอะไรแตกต่างกันบ้างในแต่ละ OS มี system default เป็นอย่างไร และ animation ต่างๆ
เมื่อจบจดหมายนี้แล้ว และทางแก้ปัญหาหล่ะ?
คิดนอกกรอบและ animation
แล้วจะทำอย่างไรให้ทำงานกับฝั่ง designer ให้งานออกมาราบรี่นหล่ะ? ให้มองว่าเป็นงานที่เราต้องทำร่วมกัน และทำตัวให้เหมือนลิงชิมแปนซี
แบบนี้
จะปิดงานแล้วเนอะ อย่าลืมทำ survey กันก๊อนนนนนนนน
ในงานโพสต์ #mobconf2019 แบบ publish และแจกเสื้อโปโลสีดำที่สตาฟใส่กัน 3 รางวัล
ปีนี้คนมางานทั้งหมด 324 คน ซึ่งมากกว่าปีที่แล้วเนอะ และคนมา check-in 70% จากทั้งหมด
ขอบคุณ sponsor partner individual sponsor speaker staff และทุกคนที่ซื้อบัตรจ้า
แน่นอนปีหน้ามีจัดแน่นอน ปักหมุดไว้ในปฏิทินด้วยนะเออ ส่วนทางเราขอคิดหัวข้อพูดก่อน จะได้ส่ง paper ไปจ้า
จากนั้น After Party ที่ร้าน Kenshin Izakaya ดีที่เจอพี่เอก เจอพี พอไหวอยู่ 55555 ได้พูดคุยกันกับหลายๆคนบ้าง
ปล. ชุดที่เราใส่แปลกๆ คือไปงานแต่งเพื่อนต่อจ้าา
แต่ที่เด็ดคือเมนูของร้านจ้า ขอรีวิวแปปนึง จะได้ทานตามกันได้ ซึ่งอันนี้พี่เอกแนะนำมาอีกทีจ้า บวกกับที่เราได้ทานไปนิดนุง
- เบียร์ในงาน support 3 ขนาด ซึ่งขนาดซูโม่ดันกลายเป็นเมนูลับเฉยเลย คนไม่ค่อยรู้กันเท่าไหร่ จากการที่พี่เอกสอบถามคนรอบข้าง (ที่ลับเพราะว่า ตรงที่วงสีแดงไม่มีขนาดซูโม่ให้ดู ดันไปอยู่กับเมนูเบียร์รสชาติอื่นๆนี่แหละ)
- เบียร์อื่นๆก็น่าสนใจแต่ทางงานไม่ได้ support เรา มีเบียร์เสาวรส มะม่วง มะเขือเทศ น่าสนใจเนอะ อันนี้แอบไปสืบทราบเองคือมีเบียร์ลาเลนเดอร์ด้วยจ้า
- เครื่องดื่มซาวานั้น เป็นแบบม็อคเทล ค็อทเทล บางเมนูสามารถไม่ใส่แอลกอฮอลได้ มีแค่ ไฮบริคซาวา (นํ้าดอกชบาผสมคอลลาเจน /อันนี้อร่อย เราสั่งอันนี้ 555) อะโอะอิ ซาวา (แอปเปิ้ลเขียว) และ เคียโฮ ซาวา (องุ่น) แอบเสียดายที่ไม่ได้ลอง อุเมะ ซาวา ที่เป็นบ๊วยอ่ะ
- สาขาที่อโศกคือบรรยากาศจะเหมือนญี่ปุ่น แบบแน่นๆหน่อย มี 4 ชั้น
- กุ้งเล็กทอด ประมาณแบบน้องนิกี้ BNK48 เล็กแต่แซ่บ แต่อันนี้เล็กแต่ได้เนื้อกุ้งเน้นๆ ซึ่งเมนูแบบนี้ที่นึกออกคืออิปุโดะราเมน สภาพห่วยกว่าของร้านนี้มาก
- Tako Wasabi เป็นปลาหมึกสดๆ มาพร้อมกับวาซาบิ ต้องคลุกก่อนทานจ้า อร่อย
- Okinawa Cream Cheese เมนูดันติดกับปลาหมึกแล้วคนดันไม่เห็น ก็คือครีมชีสเป็นลูกเต๋าน้อยๆ มาพร้อมงาดำและสาหร่ายเพื่อเพิ่มความหอม
- ปลาซาบะดองลนไฟ อันนี้เห็นสั่งทุกโต๊ะ ก็คือเขาเอาซาบะดองใส่จาน แล้วเอามาลนไฟ หื้มมมม มีความเปรี้ยวๆนิดๆ เนื้อนุ่ม อร่อยมากกกกกก เมนูนี้รู้สึกว่าเป็นเมนูประจำร้าน ใครไม่กินถือว่าพลาดจ้า
ตอนนั้นพี่เอกเดินไปเม้าท์กับโต๊ะอื่นต่อ แล้วมีคุณเอ็มที่เป็น speaker เดินมาคุยกับโต๊ะที่เรานั่ง มีคนสงสัยเรื่องเอาพวกไฟล์ config.json แล้วหากันไม่เจอเมื่อแบ่ง product flavour อะไรแบบนี้ สักพักพีเดินมาเม้าท์แปปนึง แล้วก็ขาย Blacklens มั้งนะ
ระหว่างนั้นเพื่อน messenger มาตาม เมื่อไหร่จะถึงงานแต่ง บ่นว่าเรามาช้า 55555 สักพักด้วยความที่ฝนใกล้จะตกด้วย และใกล้เวลาเลยไปงานแต่งเพื่อนต่อจ้า พอถึงแถวโรงแรมฝนตกหนักมาก เลยต้องเข้าตึกเพื่อเดินลงมาเช้าโรงแรมนี่แหละ เป็นอันจบสิ้นจ้า ซึ่งไปงานแต่งคือเจอเพื่อนที่ภาคเยอะมากกกกกกก คือตั้งแต่เรียนจบมางานนี้เจอเยอะสุด ได้อัพเดตชีวิตเพื่อนๆกัน และแน่นอนเราฟังหลายเรื่องมากๆจนเกือบจำบทสนทนาตอน after party ไม่ได้ซะแล้ว ฮ่าๆ
ปิดท้ายบล็อกนี้แบบดื้อๆด้วย swag ของงาน mobile conf และสติ๊กเกอร์ Kotlin Weekly จ้า :P
ปล. อยากพาน้องๆในทีมไปสัมผัสร้านอิซากายะสักครั้งหนึ่ง
บล็อกของท่านอื่นๆในงานนี้จ้า
พี่คนนี้ลงทุนบินมาจากขอนแก่นเพื่อมางานนี้โดยเฉพาะ
คุณพี่สมเกียรติ์ดอทซีซีก็มานะ
สาย iOS Dev ก็มาจ้า ปล. เห็นด้วยกับ session สุดท้ายตอนเช้าค่ะ
ส่วน video ย้อนหลังรอเพจ GuCode เน้อ
สุดท้ายฝากร้านกันสักนิด ฝากเพจด้วยนะจ๊ะ