Kotlin Generation : เรื่องราวของการเปลี่ยนถ่ายยุคสมัยของชาว Android Developer

android Jun 10, 2018

ตอนนี้เราเริ่มเขียน Kotlin อย่างจริงจังแล้ว และหลายๆคนอยากรู้จริงจริ๊งงงงง ว่าเขียน Kotlin แล้วลืม Java เลยหรือเปล่า แล้วต้องทำอย่างไรบ้าง

Kotlin Generation ดรุณีสมัยก็มีแล้ว ทำไมจะมี kotlin สมัยไม่ได้ ปล. อันนี้เป็นอัมบั้มแปดคนชุดแรก ;_;

อย่างที่เราทราบกันดีอยู่แล้วเนอะ ว่าในงาน Google I/O เมื่อปีก่อน เขาประกาศว่าภาษา Kotlin เป็นภาษา Official นึงในการเขียน Android

ซึ่งเราก็เพิ่งรู้จักชื่อภาษา Kotlin มาประมาณปีนึง และเริ่มได้ทำความรู้จักจริงๆ ตอนมางาน Kotlin Workshop นั่นแหละ

มาเรียนรู้ Kotlin ที่งาน Kotlin Workshop กันเถอะ
สวัสดีทุกท่าน เราก็เป็น Android Developer มาพักนึงแล้ว และได้ตามข่าว Google I/O 2017 ซึ่งภาษา Kotlin จะเป็นภาษา Official อีกภาษานึง ที่ไว้เขียน Android Application

และงาน Android Bangkok 2018 ที่ผ่านมา บรรดา speaker ก็ได้กล่าวถึงว่า มาใช้ Kotlin กันเถอะ ชีวิตจะดีขึ้น ซึ่งจริงๆเราก็เหมือนโดนป้ายยามาสักพักตั้งแต่ตอนไป workshop แล้วแหละ และเราเองก็ได้เริ่มเขียน Kotlin บน production ตั้งแต่ต้นปีนี้เลย

และในงาน Google I/O 2018 ที่ผ่านมา ก็มีหลายๆ session ที่พูดถึง Kotlin ด้วยหล่ะ

เริ่มที่ Developer Keynote ก่อนเลยจ้า …

รูปจากพี่เอกในงาน Google I/O 18 จาก session Developer Keynote https://www.youtube.com/watch?v=flU42CTF3MQ

Android Developer เริ่มมาใช้ Kotlin และมีตัวเลขที่เติบโตขึ้นทุกเดือน โดยมีเขียนแอปด้วย Kotlin ถึง 35% และ 95% บอกว่า ใช้แล้วชอบมาก และเข้าใจว่า แอปในสไลด์นี้เป็นแอปที่เขียนด้วย Kotlin นะ

อย่าง Protips ก็บอกไว้เลยว่า เริ่มต้น Android ไม่ต้องไปเรียน Java แล้ว เริ่มที่ Kotlin เลยแล้วกัน

รูปจาก session Protips: a fresh look at advanced topics for Android experts (Google I/O ’18) : https://www.youtube.com/watch?v=eHjHlujp3Tg&index=23&list=PLWz5rJ2EKKc9Gq6FEnSXClhYkWAStbwlC

จริงๆเจ้า Document ฝั่ง Android ก็เริ่มมีตัวอย่างที่เป็น Kotlin บ้าง

ref: https://developer.android.com/training/data-storage/files

และในงาน Google I/O 18 ก็เริ่มใส่ตัวอย่างโค้ดที่เป็น Kotlin มาบ้างแล้ว

ขนาดของออกใหม่อย่าง Android Jetpack ยังมี Kotlin เป็นพื้นฐานเลยนะ

สามารถอ่านเพิ่มเติมได้ที่นี่

NuuNeoI - รู้จัก Android Jetpack แบบจัดเต็ม เครื่องมือเร่งการพัฒนาแอป ฯ แอนดรอยด์ให้เร็วและโค้ดสวยงาม
บทความเกี่ยวกับแอนดรอยด์บทความแรกในรอบปีกว่า ๆ หลังจากห่างหายไปนานมาก วันนี้ขอกลับมาในเรื่องที่เราแอบรู้สึกว่าน่าสนใจมากในงาน Google I/O 2018 อย่าง “Android Jetpack” ซึ่งน่าจะเป็นหนึ่งในเครื่องมือใหญ่

และในงานก็มี session การเขียน Kotlin โดยเฉพาะ ซึ่งเขาก็ได้บอกว่า มันไม่ได้ยากนะยูว เรามาเริ่มไปพร้อมๆกันนะ

How to Kotlin ภาษานี้มันเขียนยังไงนะ จาก Google I/O 18
ตอนต้นเขาได้เกริ่นนำไว้ว่า เป็นภาษา Kotlin เป็น 1 ในภาษาที่ Developer ทั้งหลายรักสุดๆบนโลกใบนี้ เอ๊ะมันจะจริงไหมน๊าาา
ปล. ตอนแรกหาหัวข้อแจ่มๆที่จะพูดใน Code Mania 111 ไม่ได้ เปลี่ยนเรื่องบ่อยมากจนมาจบที่เรื่องนี้ คิดว่าน่าจะเป็นประโยชน์ด้วย เพราะประเด็นเรื่อง Kotlin คนก็พูดถึงกันเยอะด้วย และงาน meetup น่าจะเหมาะกับการโชว์อะไรโหดๆมากกว่าอ่ะ อีกอย่างขี้เกียจทำ demo ด้วย เพราะสองครั้งที่ผ่านมาที่เป็น speaker ต้องทำ demo ทั้งสองครั้งเลย ครั้งนี้เลยอยากจะชิวๆนิดนึง แบบเอาเรื่องที่ไม่หนักมากแล้วกันงี้

ข้อดีและข้อเสียที่ต่างกัน ระหว่าง Java และ Kotlin

เดี๋ยวหาว่าอวย เดี๋ยวหาว่าแอบมาป้ายยา เริ่มที่ข้อดีก่อนเลย

Null Safety

เคยไหม ที่ต้องมา check ว่าค่าที่ได้รับนั้น มันเป็น null ไหม อาการแบบนี้พบบ่อยใน adapter ทั้งหลาย ตอนเวลาที่เรา check ว่าเจ้า adapter ได้รับ item มากี่ตัว

@Override
public int getItemCount() {
    return mItems != null ? mItems.size() : 0;
}

เขียน Kotlin ก็เหลือแค่นี่เองอ่ะ

override fun getItemCount() = mItems.size

Less code, Less bugs, Read easier

การเขียน Kotlin ทำให้เราเขียนโค้ดต่างๆสั้นขึ้น เช่น class model จะทำให้โค้ดสั้นขึ้นมาก

ref: https://www.toptal.com/android/kotlin-boost-android-development

และเจ้า Kotlin มันจะเปลี่ยนนิสัยของเรา โค้ดอันไหนที่เราไม่จำเป็นต้องใช้มันจะขึ้นสีเทาๆแบบนี้ ให้เราลบออก นี่เป็นตัวอย่างนึง

และยังมีตัวอย่างอื่นๆอีก ติดตามชมจ้า

Similar with Swift

ด้วยความที่มี syntax อะไรหลายๆอย่างคล้ายกัน ระหว่าง Swift กับ Kotlin ทำให้ iOS Developer และ Android Developer สามารถอ่านโค้ดซึ่งกันและกันได้เข้าใจมากขึ้นนั่นเอง อันนี้ยืนยันจากคนในทีมเลยทีเดียว ตัวอย่างเช่น

จาก E-book “The Swift Programming Language” บน iBook
อันนี้เป็นสไลด์งาน เขียน Swift กันค่ะ

Low Learning Curve

ถ้าเคยเขียน Android หรือเขียน iOS ด้วย Swift สามารถเรียนรู้ได้ไม่ยาก จากสาเหตุข้อข้างบน และก็ไม่ได้ต่างจากการเขียนแอปด้วย Java เท่าไหร่

Free Lambda

ใน session How to Kotlin? ใน Google I/O 2018 ได้กล่าวไว้ว่า

Mindset อย่างนึงที่เปลี่ยนไปสำหรับคนที่เขียน Java แล้วย้ายไป Kotlin คือ เราสามารถใช้เจ้า lambda ได้ตามใจชอบเลย

ซึ่งเราสามารถใช้เจ้านี่มากขึ้นกว่าใน Java แน่นอน

https://stackoverflow.com/questions/41328583/kotlin-what-are-named-lambda-arguments-used-for

Work together with JAVA

สามารถเพิ่มเจ้า Kotlin ใน project เก่าๆได้เลย และสามารถทำงานร่วมกันได้ ไม่ต้องเสียเวลามานั่งปั้นโค้ดใหม่ใน project เดิม และนอกจากจะทำงานร่วมกันกับ Java ได้แล้ว ยังทำงานร่วมกันกับ js ได้อีกด้วยนะ ทีนี้สาย web front-end ก็น่าจะสบายขึ้น(มั้ง)

Tool Support

สาเหตุที่ทำงานด้วยกันได้ เพราะ tool ที่มีสามารถรองรับ Kotlin ได้หล่ะสิ เพราะทาง Android ก็ support ทั้งสองภาษานั่นเอง

แล้วก็ทาง Google ออกอะไรใหม่ๆมา support Kotlin ด้วยนะ

Developer Keynote https://www.youtube.com/watch?v=flU42CTF3MQ

แล้วเราจะเริ่มต้นยังไงดีหล่ะ

ก่อนอื่นต้องลง Android Studio ก่อนสิ ลงเวอร์ชั่น 3.0 ขึ้นไปนะ ซึ่งเข้าใจว่า Android Developer ลงเวอร์ชั่นล่าสุดแล้วใช่ไหม

จากนั้นลง plug-in ที่ชื่อว่า Kotlin แบบนี้

ลงเสร็จ restart Android Studio ซะ ก็ใช้ได้แล้วจ้า

ลอง re-check ดู ต้องได้แบบนี้นะ

ถ้าอยากอ่านวิธีการลงแบบละเอียด จิ้มที่นี่เลย

Kotlin for Android 101 — Lecture 1: Just a Plugin Away
Install Kotlin นี่อย่างง่าย แค่ install Kotlin plugin ใน Android Studio แล้วสั่ง config ก็จบแล้ว อันนี้ใช้ Android Studio 2.1.2 กับ Kotlin 1.0.3 จากนั้นกด cmd+shift+a เพื่อเปิด Find Action…
Getting started with Android and Kotlin - Kotlin Programming Language
This tutorial walks us through creating a simple Kotlin application for Android.

การนำไปใช้ใน project เพิ่มเจ้านี่ลงไปใน build.gradle ของ project

buildscript {
    ....
    dependencies {
        ...
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.30"

    }
}

และใส่ dependency และ plug-in ของ Kotlin ลงใน build.gradle ของ module app

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

...

dependencies {
    ...

    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.2.40"

    ...
}

...

หรือจะเพิ่มแบบนี้ก็ได้นะ

หลายๆคนคงเคยใช้แล้วเนอะ แปลง Java เป็น Kolin ได้ด้วย แบบนี้

สำหรับโปรเจกใหม่ๆ ถ้าเครื่องเราลง plug-in แล้ว ติ๊กทีเดียวได้เลย


ความแตกต่างระหว่าง Java และ Kotlin

ไม่เป็นการเสียเวลา ใส่แว่นดำแล้วเขียนโค้ดไปด้วยกันเลยจ้าาาาา

ประเภทตัวแปร หลายๆคนจะทราบว่ามี mutable และ immutable แต่ๆ มันไม่ใช่ซะทีเดียวนะ งั้นแบ่งใหม่ๆ แล้วกัน

  • mutable : สามารถเปลี่ยนค่าตัวแปรได้ เช่น var a = 1 ถ้าเราไม่อยากใส่ค่ามันไว้ก่อน สามารถใช้แบบนี้ได้ lateinit var a : Int แล้วไปใส่ค่าให้มันทีหลัง ตัวแปรชนิดนี้จะมาพร้อม get() และ set()
  • read-only variable : ไม่สามารถเปลี่ยนค่าได้ จะเหมือนเจ้า final เลย อารมณ์เดียวกันกับ const เช่น val pi = 3.14 แต่เจ้า const จริงๆ คือ const val pi = 3.14 ซึ่งตัวแปรชนิดนี้เราสามารถใส่ค่ามันได้แค่ครั้งแรกครั้งเดียว จากนั้นจะใส่ค่าทับไม่ได้ เป็นตัวแปรชนิดอ่านอย่างเดียวเนอะ แน่นอนมาพร้อม get()

และมีอีก type นึง ไม่สิ เหมือนเป็น sub-set ของ mutable type มากกว่า คือ Nullable type คือ ตัวแปรนั้น สามารถเป็น type หรือ null อย่างใดอย่างหนึ่งได้ เช่น 
var b: String?

Mutable vals in Kotlin
When I first learned Kotlin, the difference between val and var seemed simple: val means immutable and var means mutable. The truth is more nuanced than that: val does not mean immutable, val means read-only. That means that you’re not allowed to explicitly write to a val, but it doesn’t guarantee…

Properties and Fields: Getters, Setters, const, lateinit - Kotlin Programming Language

การเขียน class Activity/Fragment ต่างๆ

ด้วยความที่ Kotlin โค้ดมันจะสั้นมาก ดังนั้นเจ้า override ที่ไม่ใช้ มันจะเป็นตัวสีเทา ดังนั้น ใส่ที่จำเป็นต้องใช้เท่านั้น จึงทำให้โค้ดสั้นมาก แบบนี้

ใน fragment เราใช้แค่ 2 อันหลักๆ คือ

  • onCreateView : ไว้ใส่ตัว layout ของ fragment
  • onViewCreated : ตรงนี้เราจะใส่การทำงานอะไรก็ตามแต่ใน fragment ได้เลย เย้

การใช้ Kotlin KTX

ปกติเราจะอ้างอิงแต่ละตัวใน layout ด้วย id ดังนั้น ใน Java จะใช้ findViewById

Button button = findViewById(R.id.button);
button.setOnClickListener({           
    @Override            
    public void onClick(View view) {                
        // Make it happen           
    }        
});

หรือบางคนอาจจะใช้ Butterknife (ซึ่งน่าจะ obsolete ไปแล้ว)

เคยลองอัพ Android API ให้เป็น version 27 แล้วเกิดปัญหา มีคนเจอ error เหมือนกันเป๊ะ ถามกันไป แก้กันมา สุดท้ายเฮียแกบอกว่า ลบออกแล้วใช้ findViewById อ้าววววเห้ยยยย ไม่เหมือนที่เคยใช้นี่นาาา ref. https://github.com/JakeWharton/butterknife/issues/963
@BindView(R.id.button) Button button;
@OnClick(R.id.button) void clickTodoSth() {
    // Make it happen
}

หรือจะใช้การ binding แนว MVVM (ซึ่งเราคิดว่าน่าจะมีคนใช้ท่านี้น้อย ณ ตอนนี้นะ)

แต่สำหรับ Kotlin ใช้ KTX เนอะ ในการระบุ id ของแต่ละตัว โดยไม่ต้องใช้ค่าข้างบนเวลา แค่ import layout เข้ามาใน class เท่านั้นเอง

import kotlinx.android.synthetic.main.<layout_name>.*

button.setOnClickListener {
    // Make it happen
}

ปล. เรียก id ข้าม layout ไม่ได้นะจ๊ะ เพราะมันไม่รู้จักว่าเราเรียกอะไรมากงี้

Model Class

อันนี้พูดแบบรวบๆนิดนึง ปกติเราสร้างก้อน Object ก้อนนึงมีส่วนประกอบอะไรบ้างหล่ะ ชื่อตัวแปร ประเภทตัวแปร getter setter แบบนี้

public class User {
    private String name;
    private int age;

    public User(String n, int a) {
        name = n;
        age = a;
    }

    public int getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

แต่เจ้า Kotlin ทำให้ไฟล์ model class ของเราสั้นมาก สั้นสุดๆ แบบนี้

class User(val name: String, val age: Int)

เราไม่จำเป็นต้องไปใส่ getter/setter แบบเปลืองๆแบบนั้นเลยเนอะ

Model class with Parcelable

ที่ใส่เจ้า Parcelable ก็เพื่อรับก้อน object data จาก API มาได้อย่างครบถ้วนสมบูรณ์ ซึ่งขอแปะรวบทั้งของ Java และ Kotlin ซึ่งฝั่ง Kotlin ก็โค้ดสั้นกว่าอะเนอะ

เพิ่มเติมอ่านได้ที่นี่จ้า

[Android Code] ภาษา Kotlin กับการทำ Parcelable ในแอนดรอยด์
จะว่าไปนี่เป็นบทความแรกเลยนะเนี่ยที่พูดถึง Kotlin โดยเฉพาะ ซึ่งเกิดมาจากการที่เจ้าของบล็อกได้ใช้ภาษา Kotlin ในการเขียนแอปฯแอนดรอ...

Companion Object

เนื่องจากเจ้า Kotlin ไม่มี static ดังนั้นท่าปกติที่เราส่งค่าจาก activity หรือ fragment ไปยัง fragment เราจะสร้าง function นึงเพื่อรับค่ามา ซึ่งคิดว่าทุกคนน่าจะใช้ชื่อคล้ายๆกัน คือ newInstance()

public static SampleFragment newInstance(String name) {        
    SampleFragment fragment = new SampleFragment();        
    Bundle bundle = new Bundle();    
    bundle.putString(BUNDLE_GET_STRING, name)    
    fragment.setArguments(bundle);        
    return fragment;    
}

พอเอาโค้ดเจ้าด้านบนไปก็อปแปะบนไฟล์ .kt ผลลัพธ์ที่ได้เป็นแบบนี้

companion object {
    fun newInstance(name: String?): SampleFragment {
        val fragment = SampleFragment()
        val bundle = Bundle()
        bundle.putString(BUNDLE_GET_STRING, name)
        fragment.arguments = bundle
        return fragment
    }
}

วิธีการเรียกใช้ก็แสนจะง่าย แบบนี้

SampleFragment.newInstance("Cherprang")

ทำไมถึงประกาศ function หรือ variable ที่เป็น static ใน Java ใน companion object หล่ะ ?

เพราะว่า เราต้องการให้ class อื่นๆเรียกเจ้า newInstance ได้หล่ะสิ

แล้วมันต่างจาก function ที่เป็น pubilc ไหมง่ะ?

ต่างสิ เพราะว่าเปน fragment class ไง เราไม่สามารถเรียก function ที่เป็น public มาใช้แบบตรงๆได้แบบนี้ ถ้าเป็น class ปกติก็สามารถเรียกใช้ public function ได้เลย

ถ้าสมมุติว่าเราไม่ได้โยนค่าอะไรไปให้มันเลย จะมาแบบสั้นๆแบบนี้

//Java
public static SampleFragment newInstance() {        
    SampleFragment fragment = new SampleFragment();      
    return fragment;    
}

จะได้เป็น

//Kotlin
fun newInstance() = SampleFragment()

Getter/Setter

แต่ถ้าอยากใส่ getter/setter ต้องทำยังไงดีน๊าาา?

บางอย่างจำเป็นต้องใส่อ่ะ ทำไงดี ตัวอย่างง่ายๆ สมมติว่าเราจะ save ค่าบางอย่างไว้ใน SharedPerferences เราต้องมาใส่ท่านี้ซํ้าแล้ว ซํ้าเล่า ตามจำนวนตัวแปรที่เราใช้

public boolean getIsLogin() {
    return preferences.getBoolean(PREFERENCE_KEY_IS_LOGIN, false);
}

public void setIsLogin(boolean isLogin) {
    editor.putBoolean(PREFERENCE_KEY_IS_LOGIN, isLogin);
    editor.commit();
}

และใน Kotlin ก็ใส่แบบนี้

var isLogin: Boolean
get() = preferences.getBoolean(PREFERENCE_KEY_IS_LOGIN, false)
set(value) {
    editor.putBoolean(PREFERENCE_KEY_IS_LOGIN, value)
    editor.commit()
}

แรกๆเราก็ใส่ผิดนะ มีหลักการใส่ ดังนี้

ประกาศตัวแปรก่อน จากนั้นใส่คำว่า get หรือ set ลงไป มันจะขึ้นมาเป็นแบบนี้

สำหรับเจ้า set นั้น เอา value มันมาใช้ในปีกกานะเออ อย่าเอาชื่อตัวแปรไปใส่ในนั้นนะ ไม่งั้นมันจะพังไปเลย

constructor

ใน Java เราจะชินตากันกับแบบนี้

class SomethingInTheApp {
    public somethingInTheApp(Context context) {
        this.mContext = context;
    }
    ...
}

และถ้าเอาไปก็อปแปะแล้วแปลงเป็น Kotlin จะเป็นแบบนี้

class SomethingInTheApp {
    constructor(context: Context) {
        this.mContext = context
    }
    ...
}

แล้วมันจะขึ้นแบบนี้มา อ่ะลองซะหน่อย

ออกมาจะพบความมหัศจรรย์แบบนี้

class SomethingInTheApp(context: Context) {
    ...
}

และเราสามารถนำค่าที่เราประกาศ constructor ไปใช้ต่อ โดยสามารถประกาศตัวแปร local เพื่อนำมาใช้ใน class แบบนี้

// Kotlin
class SomethingInTheApp(context: Context) {
    private var mContext = context
    ...
}

สั้นๆอีกตัวอย่างนึง สมมุติว่าเราสร้าง class Animation มาตัวนึง ใครที่อ่านบล็อกเราน่าจะจำได้ จะประมาณนี้

public class AnimationView extends LinearLayout {
    ...

    public AnimationView(Context context) {
        super(context);
        ...
    }

    public AnimationView(Context context, AttributeSet attrs) {
        super(context, attrs);
        ...
    }

    ...

}

พอเอามาก็อปแปะจะดูน่าเกลียดมากๆ แถม error เต็มเลย ที่ถูกต้องเป็นแบบนี้

class AnimationView: LinearLayout {

    constructor(context: Context) : super(context) {
        initialize(context)
        ...
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        initialize(context)
        ...
    }
}

โดยเราใช้เจ้า constrcutor แทนชื่อ class แล้วเจ้า super ก็จะอยู่หลัง : และถ้าเราอยากให้ทำอะไรบางอย่าง ก็ใส่ปีกกาหลัง super ได้เลย

ถ้าเรามีเจ้า consturctor แค่ตัวเดียวหล่ะ มันจะยุบเหลือแค่นี้

class AnimationView(context: Context): LinearLayout(context) {
    init {
        initialize(context)
        ...
    }
}

All about class :

รู้สึกว่าประเภทของ class จะมีเพิ่มขึ้นกว่าปกติ ดังนั้น ขอยกอันที่เราใช้บ่อยๆแล้วกัน

  • Open Class เหตุเกิดจากการที่เราเริ่มเขียน Kotlin แรกๆ เราทำ BaseFragment class มาตัวนึงมาให้ fragment อื่น แต่เราไม่สามารถ extends BaseFragment ตัวนี้ได้ มันจะขึ้นว่า Can not inherit from final class เพราะว่าตัว class มันเป็น private อยู่ จึงต้องใส่ open ไว้ข้างหน้า เราจึงจะสามารถใช้ BaseFragment และ override function ได้
open class BaseFragment : Fragment() { ... }
Can not inherit from final class
I have just created my first android library. At another application I want to extend a class from the it. But it shows me an error: “Cannot extend from final ’library.com.kukaintro.activities.Kuka...

Classes and Inheritance - Kotlin Programming Language

  • Sealed Class : เป็น class ที่หน้าตามันจะคล้ายๆการสร้าง enum และ sub-class ในเจ้า sealed class นี้ สามารถมีได้หลาย instance และเก็บ state ได้ เอ๊ะ ทำไมคอนเซปมันคล้ายๆ state ใน vuex หรือ redux เลยนะ ตัวอย่าง เช่น Routing ใน Fuel นั่นเอง แหะๆ
sealed class ProfileRouting: FuelRouting {

    val PARAM_AUTH = "Authorization"

    override val basePath: String
        get() = Constant.BASE_PATH

    class getProfile(val token: String): ProfileRouting() {
        override val method: Method
            get() = Method.GET

        override val path: String
            get() = "/users"

        override val params: List<Pair<String, Any?>>?
            get() = null

        override val headers: Map<String, String>?
            get() = null
    }
}

Sealed Classes - Kotlin Programming Language

  • Data Class : ว่าง่ายๆคือก้อน Object ดีๆนี่เอง ก้อนนี้จะบรรจุค่าต่างๆที่เราต้องใช้ เล่ากันง่ายๆมันก็คือ class model นั่นแหละ เจ้านี่มาเป็น package มาพร้อมกับ hashCode(), equals(), copy() สามารถหยิบมาใช้ได้เลยจ้า
data class User(val name: String, val age: Int)

Data Classes - Kotlin Programming Language

Listener

เอาแบบง่ายๆ คือ กดปุ่มแล้วทำอะไรสักอย่าง ถ้าแบบเดิมๆจะเป็นอย่างนี้

Button button = findViewById(R.id.button);
button.setOnClickListener( {
    @Override
    public void onClick(View v) {
        //Make it happen
    }
});

ถ้าเป็น Kotlin หล่ะ

button.setOnClickListener{
    //Make it happen
}

เห็นม่ะ ดูง่ายมากๆเลย เพราะใช้เจ้า lambda ช่วยไงหล่ะ

Override Function

การเรียก Object ตัวนึงที่มีการ override ค่าข้างใน ง่ายๆเลย คือ นาฬิกาจับเวลานั่นเอง เดิมทีเราจะเรียกแบบนี้ใน Java เนอะ

new CountDownTimer(30000, 1000) {

    public void onTick(long millisUntilFinished) {
        mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
    }

    public void onFinish() {
        mTextField.setText("done!");
    }
}.start();

โดยเจ้า CountDownTimer นี้นั้นไซร้ มีการทำงาน 2 อย่างที่เราต้อง customize มัน คือ onTick() เราให้ทำอะไรระหว่างจับเวลา และ onFinish() เสร็จแล้วทำอะไรต่อ และถ้า covert เป็น Kotlin จะเป็นดังนี้

object : CountDownTimer(30000, 1000) {

    override fun onTick(millisUntilFinished: Long) {
        mTextField.setText("seconds remaining: " + millisUntilFinished / 1000)
    }

    override fun onFinish() {
        mTextField.setText("done!")
    }
}.start()

จริงๆเราลองแปลงด้วย plug-in ก่อนก็ได้นะ แล้วจำเอา ถ้าเราพิมพ์มือ จะเริ่มใส่คำว่า object ก่อน แล้วตามด้วยชื่อ object ที่เราต้องการ ใส่ body เปล่า แล้วเคาะ alt + enter ให้ implement member ออกมา ก็ได้แล้วจ้าาาา

Scoping Function
ชื่อทางการของนางอาจจะงงว่าคืออะไร แต่ถ้าบอกว่ามี also, apply, let, it, run, with ก็น่าจะนึกออกว่าคืออะไร สารภาพตามตรง เราเองก็ใช้ไม่ค่อยเป็นนัก งั้นเราขออ่านบล็อกพวกนี้ก่อนแปป

Kotlin แบบกระชับ กับ let, apply และเพื่อนๆ
คราวก่อนเราทำความรู้จัก extension function กันไปแล้วเนอะ เอาไว้ใช้แทน static utility method ได้อย่างสวยงาม ตัวอย่างบางส่วนใน kotlin-stdlib ก็ดูกันไปแล้ว แต่คุณรู้หรือไม่ว่าใน kotlin-stdlib ม…
ไขข้อสงสัยของ also, apply, let, run และ with ใน Kotlin
Kotlin เป็นภาษาที่อุดมไปด้วยความสามารถหลายๆอย่างที่ทำให้คนเขียน Java แบบเดิมๆรู้สึกว่าโลกนี้มันช่างสวยงามเหลือเกิน ถึงแม้ว่าจะมีโคตรเยอะก็ตาม ซึ่งหลายๆคนน่าจะได้สัมผัสกันแล้วก็คือคำสั่ง let เนอะ…

สมมุติคะว่าเราใส่ค่า attribute ต่างๆ บน object ตัวนึง เช่น มีปุ่มนึงที่เปลี่ยนหน้าตาตาม business logic ก็แล้วกัน

button.text = "Press This"
button.isClickable = true
button.background = resources.getDrawable(R.drawable.green, this.theme)

ลองคิดสิว่า ถ้าข้างบนมันเยอะกว่านี้หล่ะ โอ้ยยยย ไม่อยากจะคิด

เจ้า also กับ apply จะมาช่วยในการ set attribute ได้ง่ายขึ้น ซึ่งสิ่งที่เราระบุในนั้นจะมีผลเฉพาะ object นั้นๆเท่านั้น

ท่าแรก apply อันนี้มี this แถมมาด้วย ซึ่งแทน object นั้นๆ แต่ในที่นี้ไม่ต้องใส่ก็ได้เน้อออออ ไม่เหมือนเจ้า also ที่ต้องใส่ it เพื่อแทน object นั้นๆ

button.apply {
    text = "Press This"
    isClickable = true
    background = resources.getDrawable(R.drawable.green, this.theme)
}

แค่ท่าแรกก็ดูสวยงามน่าอ่านมากขึ้นแล้วเนอะ

ท่าสอง also จะมี it มาด้วย ซึ่ง it ก็แทน object นั้นๆ ในที่นี้คือ button นั่นเอง

button.also {
    it.text = "Press This"
    it.isClickable = true
    it.background = resources.getDrawable(R.drawable.green, this.theme)
}

แต่จริงๆ also จะเหมาะกับการให้ object ตัวนั้นทำอะไรบางอย่างเพิ่มกับเรามากกว่าแหะ เช่น

button.apply {
    text = "Cannot Press"
    isClickable = false
    background = resources.getDrawable(R.drawable.red, this.theme)
}.also {
    Toast.makeText(context, "gogo~", Toast.LENGTH_SHORT).show()}

แล้ว run กับ let หล่ะเจ้าคะ?

จริงๆเจ้า let ก็สามารถเขียนท่าเดียวกันกับเจ้า also ได้นะ

button.let {
    it.text = "Press This"
    it.isClickable = true
    it.background = resources.getDrawable(R.drawable.green, this.theme)
}

แล้วยังช่วยเรา check null ได้อีกด้วยนะ ตัวอย่างแบบขี้เกียจๆ อย่าง ExoPlayer เราต้องเก็บ state ของ player ก่อนที่เราจะ release player ทิ้งไป ด้วยโค้ดที่แสนจะขัดใจชุดนี้

if (player != null) {
    playbackPosition = player!!.currentPosition
    currentWindow = player!!.currentWindowIndex
    playWhenReady = player!!.playWhenReady
    player?.release()
    player = null
}

ดังนั้นเราใช้ท่า let ที่แทน condition not null จะได้แบบนี้ ซึ่งทำงานได้ผลเหมือนกัน

player?.let {
    playbackPosition = player!!.currentPosition
    currentWindow = player!!.currentWindowIndex
    playWhenReady = player!!.playWhenReady
    player?.release()
    player = null
}

ส่วนเจ้ารัน …

เห้ยยย คนละอันแล้ว เจ้า run แอบคล้ายๆเจ้า also ตรงใส่ไว้ข้างหลัง เพื่อนำบางอย่างจาก object นั้นๆ ไปใช้ต่อในคำสั่งอื่นๆ ประมาณนี้ นึกโค้ดไม่ออกหล่ะ

edittext.apply {
    text = "username"
    ...
}.run {
    Toast.makeText(context, edittext.text.toString(), Toast.LENGTH_SHORT).show()
}

Condition

สำหรับการใช้ condition ใน Kotlin จริงๆเราจะเขียนพวก if-else if-else-if switch-case ได้นะ แต่เราควรใช้ when นะ

ปกติทั้งใน Java และ Kotlin เขียนโค้ดแบบนี้ได้เนอะ

if (responseCode == 200_OK) {
    textResponse.text = "Successful!"
} else if (case == 401_Unauthorized) {
    textResponse.text = "Please log-in"
} else if (case == 404_NOT_FOUND) {
    textResponse.text = "cannot load data now"
} else if (case == 500_Server_Error) {
    textResponse.text = "Internal Server Error"
}

ถ้าเป็น Kotlin ใน Android Studio มันจะขึ้น suggestion ว่า ลองเขียนแบบนี้ดีไหม อะโชะ

when (responseCode) {
    200_OK -> textResponse.text = "Successful!"
    401_Unauthorized -> textResponse.text = "Please log-in"
    404_NOT_FOUND -> textResponse.text = "cannot load data now"
    500_Server_Error -> textResponse.text = "Internal Server Error"
}

โหวววววว โค้ดอย่างสั้นอ่ะ

Ternary Operator ชื่อทางการอาจจะไม่คุ้นเคย ถ้าบอกว่าเป็นการเขียนเจ้า short if จะร้องอ๋อทันที ปกติจะเขียนแบบนี้

//Java
itemSize = isTrue ? itemSize : 0;

แต่ใน Kotlin จะไม่สามารถเขียนแบบข้างบนได้นะ มันผิด syntax ต้องเขียนแบบนี้

//Kotlin
itemSize = if (isTrue) itemSize else 0
Ternary operator
Writing code with the least number of characters is definitely non-goal for Kotlin.

Null Safety

เนื่องจากเจ้า Kotlin มัน Null Safety ดังนั้นมันจะช่วย handle ความยุ่งยากในการ check null ต่างๆลง แต่ต้องเรียนรู้ syntax เพิ่มนิดหน่อยเพื่อให้ชีวิตง่ายขึ้น

สมมุติโค้ดตัวอย่างเป็นแบบนี้

print(company.department.employee.name)

? คือเจ้า safe calls

ตามความเข้าใจของเรา คือ ถ้าตัวไหนมีค่าเป็น null เราก็ได้จะ null กลับมา

print(company?.department?.employee?.name)

!! คือเจ้า not-null assertion operator

ตามความเข้าใจคือ ยืนยันว่าทั้งก้อนไม่ null นะ

ถ้าเป็น null จะเกิดอะไรขึ้นหล่ะ? ก็จะเกิด NullPointerException หรือ NPE หน่ะสิ แอปก็ crash ไปอีกกกก

print(company!!.department.employee.name)

?: คือ elvis operator ชื่อเรียกมาจากทรงผมของเอลวิสล้วนๆ

การทำงานคือ ดูค่านั้นว่ามีค่าไหม ถ้าเป็น null ให้คืนค่า string ว่างๆตัวนึงออกมานั่นเอง

val s = str ?: ""

Null Safety - Kotlin Programming Language

Loop

มีหลายหลากแบบที่ดูสวยงามกว่า Java และคล้ายๆภาษาอื่นๆที่เราเคยเขียนมา เช่น python แบบนี้

for (i in range) {
    print (i)
}

และหลักๆที่เขาใช้กัน มี forEach()

val iterator = (1..3).iterator()
// skip an element
if (iterator.hasNext()) {
    iterator.next()
}

// do something with the rest of elements
iterator.forEach {
    println("The element is $it")
}

ถ้าอยากได้ index มาด้วยก็ ForEachIndexed()

simpleList.forEachIndexed {
    index, element -> println("index = $index, element = $element")
}
Kotlin forEach & forEachIndexed method on Array, List, Map collection example

Not use many plus string, should use $

จาก session How to Kotlin? จะเห็นได้ยินเขาบอกว่า การบวก string มันเชยแล้ว ใช้ $ ดีกว่า ซึ่งมันคือการอ้างอิงค่าของตัวแปรนั้นๆ

//Java
println("a = " + a + "b = " + b + "c = " + c)

//Kotlin
println("a = $a, b = $b, c = $c")

Collection

สมมุติเราประกาศ array โง่ๆตัวนึงใน Java แบบนี้

String[] member = {"Cherprang", "Music", "Pun", "Jennis"};

ถ้าเอาไป convert ก็จะได้แบบนี้

var member = arrayOf("Cherprang", "Music", "Pun", "Jennis")

สรุปการประกาศตัวแปร array สามารถประกาศโดยใช้ arrayOf() และไม่ต้องใส่ประเภทตัวแปรไว้ใน <> นะ

และเราสามารถใช้ท่าเกือบจะคล้ายกันกับ list (listOf()) และ map (mapOf()) ได้แบบนี้

mapOf(KEY to "value")
listOf(KEY to "value")

Collections: List, Set, Map - Kotlin Programming Language

get array position

อันนี้มาแบบสั้นๆ แบบ Java จะเป็นอย่างงี้

array.get(0).count; //Java

พอเป็นใน Kotlin ก็เขียนแบบง่ายๆไปเลย จบ

array[0].count //Kotlin

สำหรับ library ที่พูดคุยกันกับ API เราจะลองใช้ Fuel ดูไหม

ขอยกไปที่บล็อกนี้แทนนะ

วิธีเปลี่ยนกระบวนท่า จาก Retrofit ไป Fuel
โปรเจกเดิมเป็น Retrofit โปรเจกใหม่ใช้ Fuel โดยคนในทีม พอเราใช้เลยงงเลยทีนี้ อะแง มันจะยากไหมน๊า

ไม่ใช่ Android Developer แล้วศึกษาภาษา Kotlin ได้ไหม?

ได้สิ เพราะเจ้า Kotlin ทำได้หลายอย่างเลยนอกจากเอาไปเขียนแอนดรอยด์ ดังนี้

  • iOS Application
  • Embedded System เช่น Raspberry Pi
  • Server side เช่น Ktor, Google Cloud และอีกหลายๆตัว
  • Website : js, react native, WebAssembly

และอื่นๆอีกมากมายที่ไม่รู้จะใส่ยังไงให้หมดในรูปเดียว


Resource

แน่นอนทุกคนอยากได้แหล่งความรู้ในการศึกษาสิ่งใหม่ๆ เราเลยเตรียมมาให้พร้อม

  • Official Website : https://kotlinlang.org/
  • อยากลองเขียนแบบยังไม่ลงอะไรที่เครื่องตัวเอง มาที่เว็บนี้เลยจ้า https://try.kotlinlang.org/
  • Codelab บางอันก็เป็นภาษา Kotlin นะ ลองทำดู เราเชื่อว่าคุณทำได้ มีเพิ่มหลังงาน Google I/O 2018 เยอะเลย https://codelabs.developers.google.com/
  • ในเว็บของ Android Developer ก็มีหัวข้อ Kotlin แยกออกต่างหากด้วย นี่ก็มาหลัง Google I/O 2018 https://developer.android.com/kotlin/
  • ถ้าอยากเรียน Kotlin ก็สามารถเข้าไปเรียนฟรีได้ใน Udacity ได้ Kotlin ด้วย ได้ฝึกภาษาด้วย จิ้มสมัครเรียนที่ https://www.udacity.com/course/kotlin-bootcamp-for-programmers--ud9011 หรือลิงค์ตรงที่ https://classroom.udacity.com/courses/ud9011
  • จริงๆบทความ Kotlin ใน medium ก็มีมากมาย ถ้าเริ่มเขียน Kotlin แล้วอยากอ่านภาษาไทย แนะนำ BlackLens เลยจ้า #ขายของ
  • สงสัยอะไรไปถามในกรุ๊ป Thailand Kotlin Developer ได้นะ
  • และสำหรับ Android Developer ทุกคน ควรเข้าไปดู #31DaysOfKotlin นะ

สุดท้าย เราเชื่อว่าพวกคุณทำได้!

แล้วมือใหม่คิดว่ามันยากไปไหมน๊าาาาา เอ้าาา เรามี Cheat Sheet มาให้ดูสักสองอันแล้วกัน เอามาปริ๊นแปะได้

MindorksOpenSource/from-java-to-kotlin
From Java To Kotlin - Your Cheat Sheet For Java To Kotlin - MindorksOpenSource/from-java-to-kotlin

https://fabiomsr.github.io/from-java-to-kotlin/

Kotlin Cheat Sheet
We prepared for you Kotlin Cheat sheet, so you can have the most important elements close at hand - it is the best everyday support for Kotlin developer. Sign up to our newsletter to get the pdf…

Reference แบบองค์รวม :

Why starting a new Android project with Java is a bad idea
I’m a programming language sceptic. i.e. I don’t jump on every new language and try to learn five new ones every year. When I find a good one I’ll stick with it. I used Java exclusively as my…
Why you should totally switch to Kotlin
I want to tell you about a new programming language called Kotlin and why you should consider it for your next project. I used to prefer Java but the last year I’ve found myself coding Kotlin…
สรุป Kotlin introduction จากงาน Thailand Developer Konference #1

สุดท้าย จงภูมิใจที่ใช้ Kotlin นะ


ไฟล์สไลด์ย้อนหลังจ้า เป็น pdf เนอะ อาจจะมีบางหน้าแอบเกินๆไปบ้าง

ฝากร้านกันสักนิด ฝากเพจด้วยนะจ๊ะ

อย่าลืมกด like กด share บทความกันด้วยนะคะ :)

Posted by MikkiPastel on Sunday, 10 December 2017

Tags

Minseo Chayabanjonglerd

Android Developer ผู้เป็นเจ้าของบล็อก MikkiPastel ที่ชอบทำหลายๆอย่างนอกจากเขียนแอพแอนดรอยด์ เช่น เขียนบล็อก เขียนแชทบอท เรียนออนไลน์ อ่านหนังสือ วาดรูปเล่น ดู netfilx สั่งอาหารอร่อยๆกัน เป็นต้น

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.