[Workshop] การนำ Asynchronous Flow มาใช้ในโปรเจก Android แบบเบื้องต้น
จากบทความที่แล้วที่สอนการใช้งาน Flow ไปแบบเบื้องต้น ในบทความนี้จะลองนำ Asynchronous Flow มาใช้ในโปรเจกจริง ๆ ในแอปกันครับ
หากใครยังไม่ได้อ่านบทความสอนการใช้งาน Flow เบื้องต้น สามารถเข้าไปดูเพิ่มเติมได้จากบทความนี้เลย
เริ่มต้นสร้างโปรเจก
โปรเจกนี้จะเป็นการประยุกต์ใช้ความรู้เบื้องต้นของ Coroutines, Flow, Retrofit, MVVM, Glide นำมาประกอบกันเป็นแอปขึ้น
เพื่อความรวดเร็วสามารถ clone โปรเจกที่มีโครงสร้างโค้ดเบื้องต้นไว้แล้วจาก repository นี้ได้เลย โค้ดนี้ได้โค้ด guide มาแล้วบางส่วน จากนั้นเราต้องทำการแก้ไขเพิ่มเติม และเพิ่มโค้ดเข้าไปให้สมบูรณ์ใช้งานได้ต่อไปครับ
สิ่งที่เราต้องมีก่อน คือ API ในการดึงข้อมูลมาแสดงผล หน้าตา JSON ของ API ที่เราจะใช้เพื่อนำมาสร้าง model ของข้อมูล ดังนี้
โครงสร้างเริ่มต้นของโปรเจก
แบ่ง package ตามโครงสร้าง MVVM ออกเป็น model, view, viewmodel
จากนั้นไปดูโค้ดเริ่มต้นทีละไฟล์ เริ่มต้นที่ package model มีไฟล์ NewsArticle ทำหน้าที่เป็น Model ของข้อมูลที่รับค่ามาจาก JSON ของ API
โค้ดส่วนของ package view ประกอบไปด้วย MainActivity, NewsListAdapter, Util จะเป็น class ในส่วนที่เกี่ยวข้องกับการแสดงผล
- MainActivity ทำการ setup recyclerView, adapter, view model ไว้ให้เรียบร้อย จากนั้นมาดูที่ function observeViewModel() ไว้รอรับข้อมูลที่ observe มาจาก view model เมื่อมีข้อมูลส่งมาก็ทำการอัพเดตให้ adapter ได้รู้
- NewsListAdapter เป็น recycle view adapter ทำหน้าที่แสดงผลข้อมูลในแต่ละ item ที่ function onAddNewsItem() รับค่าเป็น NewsArticle model จากนั้นเพิ่มเข้าไปใน list โดยเพิ่มไปในตำแหน่งที่ 0 เพื่อให้แสดงผลในตำแหน่งแรก
- Util เป็น ImageView extension ที่ช่วยในการโหลดรูปภาพโดยใช้ Glide เป็นตัวจัดการ
ต่อมาในส่วนของ package viewmodel ที่ class ListViewModel มีตัวแปร newsArticles และมีค่าเป็น mutableLiveData<String> ต่อไปเราจะต้องมาแก้ไขค่านี้ให้ถูกต้อง โดยแปลงเป็น liveData ตามแบบ MVVM pattern
หลังจากรีวิวโค้ดเบื้องต้นเสร็จแล้ว ต่อไปเป็นการลงมือเขียนโค้ดเพิ่มเติมเข้าไปเพื่อทำให้โค้ดสมบูรณ์สามารถทำงานได้จริงกัน
Step 1 ทำการ setup Retrofit
เพิ่ม Gradle dependencies
แก้ไขไฟล์ NewsArticle
เราจะต้อง map ตัวแปรใน model ให้ตรงกับค่า JSON ที่ได้รับจาก API ทำการแก้ไขไฟล์ model ของเราเพิ่มเติม โดยในนี้มีค่า urlToImage ที่ยังไม่ตรงกัน สามารถใช้ SerializedName เข้ามาช่วย map ชื่อตัวแปร กับค่าใน API ได้ โดยทำการเติม @SerializedName(“imageUrl”) ให้กับ urlToImage
สร้างไฟล์ NewsService
ต่อไปทำการสร้าง service ของเรา ด้วยการสร้างไฟล์ NewsSercviceใน package model ด้วยความสามารถของ Coroutine และ Retrofit เราสามารถเติม suspend นำหน้า function และให้ชนิดข้อมูลที่จะ return ค่าเป็น model ของข้อมูลตามรูปแบบของ JSON ได้เลย
สร้างไฟล์ NewsRepository
ทำการสร้างไฟล์ใน package model โค้ดในส่วน NewsRepository จะมีระบุ base url ของ API และมี function ที่จะเป็นตัวกลางที่ไปเอาข้อมูลจาก API ส่งไปให้ View Model
- ทำการสร้างตัวแปร newsService ซึ่งทำหน้าที่ติดต่อกับ API ด้วย Retrofit ทำการระบุ base url ของ API ใส่ Gson converter ให้เรียบร้อย และ create interface ของ NewsService
- ที่ function getNewsArticles() จะเป็นโค้ดที่เราประยุกต์การใช้ Flow ในแอปของเรา โดยเมื่อเราสั่ง newsService.getNews() ก็จะได้รับค่าจาก API มาเก็บไว้ใน newSource จากนั้นทำการลูปทีละค่า และ delay ทุก 2 วินาที จึงส่งข้อมูล emit ออกไปจนครบ
Step 2 การใช้งาน Flow
แก้ไขไฟล์ ListViewViewModel ใน package viewmodel
ขั้นตอนสุดท้ายของ workshop นี้ คือ การที่ view model ไปนำข้อมูลจาก repository มา จากนั้นทำการแปลงให้เป็น liveData เพื่อส่งไปให้ใครก็ตามที่ observe อยู่ นำค่านี้ไปใช้งาน หรืออัพเดตใน UI และด้วยความสามารถของ androidx.lifecycle:lifecycle-livedata-ktx
ทำให้เราสามารถแปลงข้อมูลจาก Flow มาเป็น LiveData ได้เลย ด้วยคำสั่ง asLiveData()
หมายเหตุ : เราสามารถนำข้อมูลจาก Flow มาใช้งานแบบปกติด้วยการใช้ collect หรือ onEach เพียงแต่บทความนี้จะพาใช้วิธีแปลงเป็น LiveData จาก Flow ด้วยการใช้งาน asLiveData ซึ่งอีกวิธีการสามารถทำได้ ดังนี้
Step 3 รันทดสอบผล
ก็เป็นอันเสร็จพิธี ในการแก้ไขเพิ่มเติมประกอบโค้ดให้สมบูรณ์ จากนั้นลองทดสอบรัน เพื่อดูการทำงานได้เลย เมื่อรันเสร็จแล้ว จะเห็นว่าแอปจะมีนำ Item มาแสดงผลเพิ่มเติมในทุกๆ 2 วินาที จนกว่าของที่ถูก emit มาจาก repository จนครบ
ข้อสรุป
นี่ก็เป็นตัวอย่างการลองนำความรู้มาประยุกต์เพื่อนำมาสร้างเป็นแอปจริง ๆ เป็นตัวอย่างการใช้งาน Flow ในแอปของเรา รวมถึงมีการติดต่อเพื่อดึงข้อมูลจากฝั่ง backend API ในการเรียกใช้งานผ่าน Retrofit เพื่อนำมาแสดงผล การจัดการเรื่องรูปภาพด้วย Glide และเขียนโค้ดในรูปแบบของ MVVM ซึ่งการได้ลองทำเป็นโปรเจกจริง ๆ จะช่วยให้เห็นภาพมากขึ้น และเป็นไอเดียนำไปต่อยอดสร้างแอปที่ใหญ่ขึ้น มีฟีเจอร์หลากหลายยิ่งขึ้นต่อไป และหวังว่าบทความนี้จะเป็นประโยชน์ต่อผู้อ่านที่สนใจไม่มากก็น้อย