[Android] มาเชื่อมต่อ Network ด้วย Retrofit2(อย่างง่ายๆ) กันเถอะ

Oat Anirut
4 min readJan 18, 2016

--

หลายท่านที่เคยเขียน Android application อาจจะได้เคยลองเขียนแอพที่ต้องมีการเรียก url ต่างๆกันมาแล้ว และหลายๆท่านก็คงทราบกันแล้วว่า ใน API 23 ก็ได้ deprecate เจ้า HttpClient ไปแล้ว ดังนั้นเห็นโค้ดนี้อยู่ในไฟล์ไหน ก็ไปตามแก้กันนะครับ

แล้วจะให้ใช้อะไรเชื่อมต่อกันหละ? ก็ตามชื่อหัวข้อเลยครับ “Retrofit2” และเพื่อความง่าย ผมจึงขออธิบายเฉพาะโหมด Asynchronouse(ทำงานใน background thread เราไม่ต้องสร้าง Thread, AsynceTask เอง) อย่างเดียวนะครับ

และใครที่เคยใช้ Rretrofit 1.0 มาแล้ว ตอนนี้ 2.0 เค้าเปลี่ยนวิธีการใช้งานไปพอสมควรครับ ถ้าสนใจก็อ่านเพิ่มจากเว็บพี่เนยได้เลยครับ

หลังจากที่ได้ลองเล่นดูก็ไม่ยากอย่างที่คิดแฮะ (แต่ก็งมอยู่นาน ทำครั้งแรกก็เงี้ย)

Overview
โปรเจ็คนี้่เราจะทำอะไรกันบ้าง? (เอาแบบง่ายๆแล้วกันเนอะ)
1. ส่ง Github username ไปที่ https://api.github.com
2. รับ json
3. นำข้อมูลมาแสดงบน UI

หลักการทำงานของ Retrofit2

หลักการทำงาน credit by. akexorcist.com

สามารถใช้ร่วมกันกับ Okhttp ได้(เจ้าของเดียวกัน) แต่บทความนี้ขอละ Okhttp ออกไปก่อนนะครับ

เอาหละ เรา Introduction กันมาพอหอมปากหอมคอกันพอแล้วเนอะ งั้นเรามาดูโค้ดกันเล้ย (New Project ให้พร้อมน้าา)

  1. ขอ Permission

อันนี้ถือว่าสำคัญมาก ถ้าไม่ขอจะต่ออินเตอร์เน็ตได้อย่างไรเนอะ

2.สร้าง Layout เพื่อกรอก Github username

activity_main.xml (form)
activity_main.xml (progress)
activity_main.xml (result)

ทั้ง 3 หน้าตานี้ผมแบ่งให้อยู่ในคนละ layout ทั้ง 3 layout นี้อยู่ใน file activity_main.xml (ดูโค้ดได้จาก Github ผมจะแปะไว้ช่วงท้ายๆ)

3. Add dependency

ตัวแรกเป็น retrofit2 จะทำให้เราสามารถใช้คำสั่งต่างๆของ retrofit ได้
ตัวที่สอง เป็น Gson converter ไว้สำหรับแปลง Json จาก Server ให้อยู่ในรูป Java(POJO)

4.findViewById และ setOnClick เจ้า Button

จะเห็นว่าผมได้สร้าง method initInstance() ขึ้นมาเพื่อแยก code ส่วนของการ binding view ออกมาจาก onCreate ทั้งนี้ก็เพื่อไม่ให้ onCreate มีโค้ดเยอะจนเกินไป เพราะอนาคตโค้ดจะงอกออกมาจาก onCreate เยอะมาก ทำไปเรื่อยๆ เราต้องหมั่นมา refactor code แยกออกมาให้เป็นหมวดหมู่นะคับ

5. setOnClickListener ให้ Button

จะเห็นว่ายังเหลือตัวแปร onBtSendClickListener ที่ยังเป็นสีแดงอยู่ ไม่ต้องตกใจ
ผมจะเอาไว้แฮนเดิลการคลิกของปุ่ม Send ก็ให้สร้างตัวแปร Global อีกตัวตามนี้เลย

ทีนี้เจ้า onBtSendClickListener ก็จะหายแดงแล้ว

*เทคนิค
ให้พิมพ์แค่ View.OnClickListener onBtSendClickListener= new จากนั้นกด Ctrl+Space มันจะมี Auto complete ขึ้นมาให้เราเลือก ให้เลือก OnClickListener ตัว Android Studio จะทำการ Generate ส่วนที่เหลือให้เราอัตโนมัติ(อย่าลืมใส่ Semi colon หลังวงปีกกาอันสุดท้ายด้วยนะ)

Ctrl+Space

เมื่อเราคลิกที่ Button Send method onClick ก็จะทำงาน แต่ตอนนี้ยังไม่ได้ใส่อะไรเข้าไป ดังนั้นกดแล้วก็จะไม่มีอะไรเกิดขึ้น ซึ่งสิ่งที่เราคาดหวังว่าเมื่อกดปุ่ม Send แล้วจะให้แอพไปติดต่อกับ server ของ Github ชะมะ ดังนั้นเราควรเขียนคำสั่งในการเชื่อมต่อ Network ตรงนี้แหละครับ แต่เราจะกระโดดไปสร้างส่วนของการเชื่อมต่อ network ให้สมบูรณ์กันก่อนนะครับ

6. สร้าง Model (POJO)
เป็น Class ที่เราจะใช้เก็บข้อมูลที่ Server ส่ง Json มา ดังนั้นชื่อตัวแปรต่างๆจะต้องเหมือนชื่อ key ใน json ด้วย โดยเราจะใช้ key name, blog, company และ generate getter ให้ทุกตัวแปรด้วยตามวัฒนธรรมของ OOP จะได้หน้าตามโค้ดตามนี้

7. API Declaration

สร้าง interface ในการระบุ url และ parameters ต่างๆ รายละเอียดก็ตามนี้เลย

อธิบาย: เราจะส่งข้อมูลไปที่ baseUrl/users/{username}
baseUrl: https://api.github.com
username: จะมาจาก String username ซึ่งมาจากการกรอกที่ EditText อีกทีเช่น ถ้ากรอกมาเป็น rakjang007

เสมือนเราเปิด url: https://api.github.com/users/rakjang007
ถ้าลองเปิดที่ Google Chrome จะเห็นโครงสร้างข้อมูลเป็น Json

(ผม copy มาแค่บางส่วนให้ดูนะ ยังมี Key อื่นๆอีกเพี้ยบ)

ซึ่งถ้าเราเปลี่ยนจาก @GET เป็น Annotation ตัวอื่นๆก็จะมีวิธีการใช้งานที่ต่างกัน เช่น

สามารถเปิด Doc ของ Retrofit2 เพิ่มเติมได้ครับ

เมื่อทำ Model และ Interface เสร็จแล้ว ต่อไปเราจะนำ 2 สิ่งนี้มาทำงานกัน แต่ก่อนอื่นขอให้สร้าง interface อีกตัว เพื่อใช้ส่ง event กลับไปที่ MainActivity ก่อน หรือใครถนัด event bus อื่นๆก็ไม่ว่ากัน

8. สร้าง Interface OnNetworkCallbackListener.java

  • onResponse จะทำงานเมื่อมี data ส่งมาจริงๆ
  • onBodyError จะทำงานเมื่อข้อมูลที่ส่งมามีปัญหาที่สามารถแสดง error ได้
  • onBodyErrorIsNull จะทำงานเมื่อข้อมูลที่ส่งมามีปัญหาแต่ไม่สามารถแสดง error ได้
  • onFailure จะทำงานเมื่อปัญหาอื่นๆ (ไม่ได้ข้อมูลแน่ๆ) เช่น ต่อเน็ตไม่ได้, url ผิด ฯลฯ

9. สร้าง Class การเชื่อมต่อ และรับ Response จาก Server

ให้สร้าง Class ใหม่ ชื่อว่า NetworkConnectionManager.java

โดย MainActivity จะเรียกใช้ method callServer โดยส่ง listener และ username เข้ามาด้วย

โดยค่า username ที่ได้จาก EditText เข้ามาแล้วส่งต่อไปที่ method getUser ของบรรทัด

การ Configuration retrofit2

baseUrl: อธิบายในข้อ 7 ไปแล้ว
addConverterFactory: เป็น converter ที่ใช้จัดการกับ Json ให้อยู่ในรูป Model สามารถปรับแต่งการ Convertor ได้ แต่ไม่ขออธิบายในบทความนี้นะคับ ใช้แบบ default ไปละกันนะครับ

สุดท้ายข้อมูลจาก Server จะถูกส่งมาที่นี่

โดยข้อมูลจะส่งมาที่ onResponse() แต่อาจจะได้เป็นข้อมูลเปล่า หรือ null ก็ได้นะต้อง Handle ดีๆ ส่วน onFailure() ก็ตามชื่อเลย ถ้า method นี้ทำงานก็หมายความว่าปัญหาอะไรสักอย่าง

ซึ่งผมจะใช้ interface onNetworkCallbackListener ที่สร้างไว้ในข้อ 8 ในการ handle event ต่างๆที่จะเกิดขึ้น

โดยใส่รายละเอียดตามนี้

อาเคร ส่วนของการเชื่อมต่อกับ network ก็เสร็จสิ้นหมดแล้ว ทีเหลือเราจะรับค่ามาแสดงผลที่ Activity กัน

10. เรียก callServer

กลับมาที่ MainActivity ถ้ายังจำได้ในข้อที่ 5 ที่เราได้ทำการ setOnClick button ค้างเอาไว้ เราจะกลับมาทำต่อกันแล้ว โดยใส่ คำสั่งตามนี้เข้าไปใน onClick()

โดยเราจะส่ง networkCallbackListener และ edUsername.getText().toString() ไปที่ method callServer

callServer ก็จะทำการไปดึงข้อมูลมาจาก Server ให้เรา

แต่มี error ที่ networkCallbackListener ใช่มั้ยล้า เพราะเรายังไม่สร้าง object นั้นเลย ให้เราไปสร้าง object ของ interface ไว้ตามนี้ ก็จะหายแดงแล้ว และส่วนนี้แหละครับที่จะรับค่ามาจาก NetworkConnectionManager ครับ

และใส่รายละเอียดเข้าไปในแต่ละ method onResponse เลย

ส่วน method ที่เหลือจะเป็น fail case ไม่ต้องใส่รายละเอียดก็ได้ หรือก็ใส่ Log เอาไว้ตรวจสอบค่าเฉยๆก็ได้

เอาหละมาถึงตอนนี้ข้อมูลของเราก็จะถูกแสดงออกมาที่ tvResult แล้ว

ไฟล์ทั้งหมดของโปรเจ็คจะได้แบบนี้ครับ

สรุปการทำงาน
1. สร้าง model (ข้อ 6)
2. API Declaration (ข้อ 7)
3. Retrofit configuration (NetworkConnectionManager.java)
4.Result handling (ข้อ 9 ทั้งหมด)

ไม่ยากเลยใช่มั้ยครับ หรือถ้าติดปัญหาตรงไหนก็ดูใน Github ได้ครับ(Github นี้ใช้ร่วมกับ บทความถัดไปด้วยนะครับ อาจมีไฟล์ที่เกินๆจากโปรเจ็คนี้มาด้วย) บทความนี้เป็นบทความแรกในชีวิต อาจยาวไป แต่ก็ตั้งใจทำเต็มที่ บทความหน้าจะทำให้ดีกว่านี้ครับ^^

บทความต่อไป เราจะมาลองเล่นเรื่อง Instance state กันนะครับ

หลายคนอาจเห็นว่าผมไม่ได้เคลื่อนไหวใน Medium แล้ว พอดีตอนนี้ย้ายไปเขียนที่ นี้แล้วครับ

https://oatrice.wordpress.com/

ขอขอบคุณข้อมูลจาก
1. http://square.github.io/retrofit/
2. http://themakeinfo.com/2015/04/retrofit-android-tutorial/
3. http://inthecheesefactory.com/blog/retrofit-2.0/th
4. https://futurestud.io/blog/retrofit-2-upgrade-guide-from-1-9
5. http://devahoy.com/posts/day-3-learn-retrofit/#
6. https://speakerdeck.com/jakewharton/simple-http-with-retrofit-2-droidcon-nyc-2015

--

--