SlideShare a Scribd company logo
POWER-UP YOUR
ANDROID-FU
WITH KOTLIN
@NICOLAS_FRANKEL
ME, MYSELF AND I
Blah, blah, blah…
@nicolas_frankel - Improve your Android-Fu with Kotlin
2
MY EXPERIENCE IN ANDROID
Back-end Java developer
Developing a To Do list
application with some
improvements
• Images
• Alarm
• Multiple lists
@nicolas_frankel - Improve your Android-Fu with Kotlin
3
MY PERSONAL CONCLUSION
Developing Android app is a
pain
Backend Java is very mature
compared to Android
High-level libraries required
to cope up with low-level APIs
@nicolas_frankel - Improve your Android-Fu with Kotlin
4
ORIGINAL STACK
Dagger 2
Butterknife
Retro-lambda
Streams
Green Robot’s EventBus
Picasso
@nicolas_frankel - Improve your Android-Fu with Kotlin
5
OUTLINE
Kotlin - the language
Libraries
• Stdlib
• Kotlin extensions for Android
• Anko
@nicolas_frankel - Improve your Android-Fu with Kotlin
6
KOTLIN
Language developed by
JetBrains
Open Source
Compiles to
• JVM bytecode
• JavaScript (experimental)
A "simpler Scala"
@nicolas_frankel - Improve your Android-Fu with Kotlin
7
KOTLIN
Functional and object-oriented
Statically typed
Null safety
No checked exceptions
Named & optional arguments
Lambdas
Extension functions
Java compatibility
(And more...)
@nicolas_frankel - Improve your Android-Fu with Kotlin
8
HELLO WORLD!
package hello // optional semicolons
// namespace-level functions
// types on the right
// no special syntax for arrays
// optional return type
fun main(args: Array<String>) {
println("Hello, world!")
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
9
SETUP - BUILD.GRADLE
buildscript {
ext.kotlin_version = '1.0.0-beta-1038'
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-
plugin:$kotlin_version"
}
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
10
SETUP – APP/BUILD.GRADLE
apply plugin: 'kotlin-android'
android {
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
test.java.srcDirs += 'src/test/kotlin'
}
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
11
SAMPLE CODE
public class AddTaskEvent extends AbstractTaskEvent {
private final List list;
public AddTaskEvent(Task task, List list) {
super(task);
this.list = list;
}
public List getList() {
return list;
}
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
12
PAIN POINTS
Verbose!
• Not specific to Android
• Unfortunately Java
@nicolas_frankel - Improve your Android-Fu with Kotlin
13
KOTLIN SOLUTION
class AddTaskEvent(task: Task, val list: List)
: AbstractTaskEvent(task)
@nicolas_frankel - Improve your Android-Fu with Kotlin
14
SAMPLE CODE
public class KeyboardDisplay {
public void show(Activity a) {
InputMethodManager imm =
(InputMethodManager) a.getSystemService(INPUT_METHOD_SERVICE);
imm.toggleSoftInput(SHOW_FORCED, 0);
}
public void hide(Activity a) {
InputMethodManager imm =
(InputMethodManager) a.getSystemService(INPUT_METHOD_SERVICE);
imm.toggleSoftInput(HIDE_IMPLICIT_ONLY, 0);
}
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
15
PAIN POINTS
Artificial grouping
Utility class
• No real Object, nor state
@nicolas_frankel - Improve your Android-Fu with Kotlin
16
KOTLIN SOLUTION
fun show(a: Activity) {
val imm =
a.getSystemService(INPUT_METHOD_SERVICE)
as InputMethodManager
imm.toggleSoftInput(SHOW_FORCED, 0)
}
fun hide(a: Activity) {
val imm =
a.getSystemService(INPUT_METHOD_SERVICE)
as InputMethodManager
imm.toggleSoftInput(HIDE_IMPLICIT_ONLY, 0)
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
17
SAMPLE CODE
SQLiteDatabase db = getReadableDatabase();
db.query(TASK_TABLE,
new String[] { T_ID_COL, T_NAME_COL },
null, null, null, null,
T_PRIO_COL);
@nicolas_frankel - Improve your Android-Fu with Kotlin
18
PAIN POINTS
@nicolas_frankel - Improve your Android-Fu with Kotlin
19
Really, pass all those null
values?
Create local variable for
ease of use
KOTLIN SOLUTION – PART 1
fun SQLiteDatabase.query(table:String,
columns:Array<String>,
selection:String? = null,
selectionArgs:Array<String>? = null,
groupBy:String? = null,
having:String? = null,
orderBy:String? = null): Cursor {
return query(table, columns, selection,
selectionArgs, groupBy, having, orderBy)
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
20
KOTLIN SOLUTION – PART 2
readableDatabase.query(TASK_TABLE,
arrayOf(T_ID_COL, T_NAME_COL),
orderBy = T_PRIO_COL)
@nicolas_frankel - Improve your Android-Fu with Kotlin
21
KOTLIN LIBRARY
Standard API for the
language
@nicolas_frankel - Improve your Android-Fu with Kotlin
22
SETUP – APP/BUILD.GRADLE
dependencies {
compile "org.jetbrains.kotlin:kotlin-
stdlib:$kotlin_version"
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
23
SAMPLE CODE
public class DisplayMetricsGetter {
public DisplayMetrics getFrom(Context c) {
WindowManager wm = (WindowManager)
c.getSystemService(WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
return metrics;
}
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
24
PAIN POINTS
Utility class
Cannot return the object
directly
• Have to create a local variable
@nicolas_frankel - Improve your Android-Fu with Kotlin
25
KOTLIN SOLUTION
fun getFrom(c: Context): DisplayMetrics {
val wm =
c.getSystemService(Context.WINDOW_SERVICE)
as WindowManager
val metrics = DisplayMetrics()
wm.defaultDisplay.getMetrics(metrics)
return metrics
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
26
KOTLIN SOLUTION
fun getFrom(c: Context): DisplayMetrics {
val wm =
c.getSystemService(Context.WINDOW_SERVICE)
as WindowManager
return DisplayMetrics().apply {
wm.defaultDisplay.getMetrics(this)
}
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
27
KOTLIN EXTENSIONS FOR ANDROID
Plugin for the Kotlin
compiler
Provide a "synthetic
property" for each widget in a
layout
@nicolas_frankel - Improve your Android-Fu with Kotlin
28
SETUP – APP/BUILD.GRADLE
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-
android-extensions:$kotlin_version"
}
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
29
SAMPLE CODE
public class AddActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.task_add_item);
View imageView = findViewById(R.id.new_task_img);
imageView.setOnClickListener(...);
}
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
30
SAMPLE CODE – WITH BUTTERKNIFE
public class AddActivity extends AppCompatActivity {
@Bind(R.id.new_task_img)
View imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.task_add_item);
ButterKnife.bind(this);
imageView.setOnClickListener(...);
}
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
31
PAIN POINTS
Do I have to detail???
@nicolas_frankel - Improve your Android-Fu with Kotlin
32
KOTLINX SOLUTION
import
kotlinx.android.synthetic.task_add_item.new_task_img
class AddTaskActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.task_add_item)
new_task_img.setOnClickListener(...)
}
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
33
ANKO
Kotlin library for Android
Mostly about replacing XML
with fluent DSL for GUI
But a lot of other niceties
@nicolas_frankel - Improve your Android-Fu with Kotlin
34
CODE SAMPLE
public class AddAlarmClickListener implements
View.OnClickListener {
@Override
public void onClick(View view) {
View rootView = view.getRootView();
ViewFlipper flip = (ViewFlipper)
rootView.findViewById(R.id.new_task_alarm_flip);
flip.setDisplayedChild(1);
}
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
35
PAIN POINTS
Cast
Setter (?)
@nicolas_frankel - Improve your Android-Fu with Kotlin
36
ANKO SOLUTION
import org.jetbrains.anko.*
class AddAlarmClickListener: View.OnClickListener {
override fun onClick(view: View) {
val parent:View = view.rootView
val flip =
parent.find<ViewFlipper>(R.id.new_task_alarm_flip)
flip.displayedChild = 1
}
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
37
CODE SAMPLE
fun show(a: Activity) {
val imm =
a.getSystemService(INPUT_METHOD_SERVICE)
as InputMethodManager
imm.toggleSoftInput(SHOW_FORCED, 0)
}
fun hide(a: Activity) {
val imm =
a.getSystemService(INPUT_METHOD_SERVICE)
as InputMethodManager
imm.toggleSoftInput(HIDE_IMPLICIT_ONLY, 0)
}
@nicolas_frankel - Improve your Android-Fu with Kotlin
38
PAIN POINTS
Map-based API
Cast
@nicolas_frankel - Improve your Android-Fu with Kotlin
39
ANKO SOLUTION
a.inputMethodManager.toggleSoftInput(
SHOW_FORCED, 0)
a.inputMethodManager.toggleSoftInput(
HIDE_IMPLICIT_ONLY, 0)
@nicolas_frankel - Improve your Android-Fu with Kotlin
40
CODE SAMPLE
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage("New list name");
EditText editText = new EditText(activity);
editText.setId(
android.support.v7.appcompat.R.id.select_dialog_listview);
String listName = global.getList().getName();
editText.setText(listName, NORMAL);
editText.selectAll();
builder.setView(editText);
builder.setPositiveButton("OK", editListNameListener);
builder.setNegativeButton("Cancel", (dialog, which) -> {
dialog.cancel();
});
AlertDialog dialog = builder.create();
dialog.show();
@nicolas_frankel - Improve your Android-Fu with Kotlin
41
PAIN POINTS
Verbose +++
Not structured
@nicolas_frankel - Improve your Android-Fu with Kotlin
42
ANKO SOLUTION
view.context.alert('New list name') {
builder.setPositiveButton('OK', editListNameListener)
negativeButton('Cancel') {
cancel()
}
customView {
editText(global.list.name) {
id = an.sup.v7.appcompat.R.id.select_dialog_listview
}.selectAll()
}
}.show()
@nicolas_frankel - Improve your Android-Fu with Kotlin
43
FINAL STACK
Dagger 2
Butterknife  Kotlin ext.
Retro-lambda  Kotlin
Streams  Kotlin
Green Robot’s EventBus
Picasso
@nicolas_frankel - Improve your Android-Fu with Kotlin
44
MIGRATION TACTICS
@nicolas_frankel - Improve your Android-Fu with Kotlin
45
Start with standard classes
• Then with Android-dependent
classes
Use Android Studio provided
migration tool
Take a class
• Migrate to Kotlin extension
• Migrate to Anko
• After each single change, test!
Repeat
PITFALL
@nicolas_frankel - Improve your Android-Fu with Kotlin
46
Null-able types
NULL-ABLE VS. NON NULL-ABLE TYPES
@nicolas_frankel - Improve your Android-Fu with Kotlin
47
Different type whether
value can be null or not
• T: cannot be null
• T?: can be null
NULL-ABLE VS. NON NULL-ABLE TYPES
@nicolas_frankel - Improve your Android-Fu with Kotlin
48
Parameter types should use
the right kind
• Know your API
• Or read the docs
• Or be conservative
MY EXPERIENCE
@nicolas_frankel - Improve your Android-Fu with Kotlin
49
More expressive
Higher-level abstractions
One single class I couldn’t
migrate
• Dagger 2 module
Q&A
@nicolas_frankel - Improve your Android-Fu with Kotlin
50
http://blog.frankel.ch/
@nicolas_frankel
http://frankel.in/

More Related Content

PPTX
Geecon - Improve your Android-fu with Kotlin
PPTX
GDG Kuwait - Modern android development
PDF
Mobile Fest 2018. Кирилл Розов. Insert Koin
PDF
KotlinAndroidLibを使ってみた
PPTX
NDRIOD PROGRAMMINLesson 2 Functions.pptx
PPTX
Lecture 12 - Maps, AR_VR_aaaaHardware.pptx
PDF
Android Development with Kotlin, Part 2 - Internet Services and JSON
PDF
What’s new in Android: Embracing era of Generative AI
Geecon - Improve your Android-fu with Kotlin
GDG Kuwait - Modern android development
Mobile Fest 2018. Кирилл Розов. Insert Koin
KotlinAndroidLibを使ってみた
NDRIOD PROGRAMMINLesson 2 Functions.pptx
Lecture 12 - Maps, AR_VR_aaaaHardware.pptx
Android Development with Kotlin, Part 2 - Internet Services and JSON
What’s new in Android: Embracing era of Generative AI

Similar to Improve your Android-Fu with Kotlin (20)

PPTX
Lesson 1 Kotlin basics.pptx........................
PPTX
Pembelajaran Basic Kotlin Kurikulum Google
PPTX
ANDRIOD PROGRAM Lesson Kotlin basic.pptx
PPTX
Lesson 6 App navigation for beginners .pptx
PDF
Android study jam session 1
PDF
You don't need DI
PDF
You Don't Need Dependency Injection
PDF
Diving into VS 2015 Day4
PPTX
Writing Kotlin Multiplatform libraries that your iOS teammates are gonna love
PPTX
Lesson 3 Classes and objects for beginnners.pptx
PDF
Kotlin workshop
PPTX
Going native with less coupling: Dependency Injection in C++
PDF
Survey_Paper
PDF
Building android apps with MVP, Dagger, Retrofit, Gson, JSON, Kotlin Data Cl...
PPTX
Compose camp 2.pptx
PPTX
pluginandplay-UtrechtJUG.pptx
PPTX
Kotlin で android アプリを作ってみた
PPTX
Building Mobile Apps with Android
PPTX
Android Study Jam 1 Day 1 | December 2021 | GDSC BVCOENM
PPTX
PluginAndPlay-AmsterdamJUG.pptx
Lesson 1 Kotlin basics.pptx........................
Pembelajaran Basic Kotlin Kurikulum Google
ANDRIOD PROGRAM Lesson Kotlin basic.pptx
Lesson 6 App navigation for beginners .pptx
Android study jam session 1
You don't need DI
You Don't Need Dependency Injection
Diving into VS 2015 Day4
Writing Kotlin Multiplatform libraries that your iOS teammates are gonna love
Lesson 3 Classes and objects for beginnners.pptx
Kotlin workshop
Going native with less coupling: Dependency Injection in C++
Survey_Paper
Building android apps with MVP, Dagger, Retrofit, Gson, JSON, Kotlin Data Cl...
Compose camp 2.pptx
pluginandplay-UtrechtJUG.pptx
Kotlin で android アプリを作ってみた
Building Mobile Apps with Android
Android Study Jam 1 Day 1 | December 2021 | GDSC BVCOENM
PluginAndPlay-AmsterdamJUG.pptx
Ad

More from Nicolas Fränkel (20)

PPTX
SnowCamp - Adding search to a legacy application
PPTX
Un CV de dévelopeur toujours a jour
PPTX
Zero-downtime deployment on Kubernetes with Hazelcast
PDF
jLove - A Change-Data-Capture use-case: designing an evergreen cache
PPTX
BigData conference - Introduction to stream processing
PPTX
ADDO - Your own Kubernetes controller, not only in Go
PPTX
TestCon Europe - Mutation Testing to the Rescue of Your Tests
PPTX
OSCONF Jaipur - A Hitchhiker's Tour to Containerizing a Java application
PPTX
GeekcampSG 2020 - A Change-Data-Capture use-case: designing an evergreen cache
PPTX
JavaDay Istanbul - 3 improvements in your microservices architecture
PPTX
OSCONF Hyderabad - Shorten all URLs!
PPTX
Devclub.lv - Introduction to stream processing
PPTX
OSCONF Koshi - Zero downtime deployment with Kubernetes, Flyway and Spring Boot
PPTX
JOnConf - A CDC use-case: designing an Evergreen Cache
PPTX
London In-Memory Computing Meetup - A Change-Data-Capture use-case: designing...
PPTX
JUG Tirana - Introduction to data streaming
PPTX
Java.IL - Your own Kubernetes controller, not only in Go!
PPTX
vJUG - Introduction to data streaming
PPTX
London Java Community - An Experiment in Continuous Deployment of JVM applica...
PPTX
OSCONF - Your own Kubernetes controller: not only in Go
SnowCamp - Adding search to a legacy application
Un CV de dévelopeur toujours a jour
Zero-downtime deployment on Kubernetes with Hazelcast
jLove - A Change-Data-Capture use-case: designing an evergreen cache
BigData conference - Introduction to stream processing
ADDO - Your own Kubernetes controller, not only in Go
TestCon Europe - Mutation Testing to the Rescue of Your Tests
OSCONF Jaipur - A Hitchhiker's Tour to Containerizing a Java application
GeekcampSG 2020 - A Change-Data-Capture use-case: designing an evergreen cache
JavaDay Istanbul - 3 improvements in your microservices architecture
OSCONF Hyderabad - Shorten all URLs!
Devclub.lv - Introduction to stream processing
OSCONF Koshi - Zero downtime deployment with Kubernetes, Flyway and Spring Boot
JOnConf - A CDC use-case: designing an Evergreen Cache
London In-Memory Computing Meetup - A Change-Data-Capture use-case: designing...
JUG Tirana - Introduction to data streaming
Java.IL - Your own Kubernetes controller, not only in Go!
vJUG - Introduction to data streaming
London Java Community - An Experiment in Continuous Deployment of JVM applica...
OSCONF - Your own Kubernetes controller: not only in Go
Ad

Recently uploaded (20)

PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
System and Network Administration Chapter 2
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
Nekopoi APK 2025 free lastest update
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
top salesforce developer skills in 2025.pdf
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
Essential Infomation Tech presentation.pptx
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PPTX
history of c programming in notes for students .pptx
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PPTX
Introduction to Artificial Intelligence
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Odoo Companies in India – Driving Business Transformation.pdf
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
System and Network Administration Chapter 2
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Nekopoi APK 2025 free lastest update
How to Migrate SBCGlobal Email to Yahoo Easily
Design an Analysis of Algorithms I-SECS-1021-03
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Operating system designcfffgfgggggggvggggggggg
top salesforce developer skills in 2025.pdf
Wondershare Filmora 15 Crack With Activation Key [2025
Essential Infomation Tech presentation.pptx
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
history of c programming in notes for students .pptx
Upgrade and Innovation Strategies for SAP ERP Customers
Introduction to Artificial Intelligence
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Design an Analysis of Algorithms II-SECS-1021-03
Odoo Companies in India – Driving Business Transformation.pdf

Improve your Android-Fu with Kotlin

  • 2. ME, MYSELF AND I Blah, blah, blah… @nicolas_frankel - Improve your Android-Fu with Kotlin 2
  • 3. MY EXPERIENCE IN ANDROID Back-end Java developer Developing a To Do list application with some improvements • Images • Alarm • Multiple lists @nicolas_frankel - Improve your Android-Fu with Kotlin 3
  • 4. MY PERSONAL CONCLUSION Developing Android app is a pain Backend Java is very mature compared to Android High-level libraries required to cope up with low-level APIs @nicolas_frankel - Improve your Android-Fu with Kotlin 4
  • 5. ORIGINAL STACK Dagger 2 Butterknife Retro-lambda Streams Green Robot’s EventBus Picasso @nicolas_frankel - Improve your Android-Fu with Kotlin 5
  • 6. OUTLINE Kotlin - the language Libraries • Stdlib • Kotlin extensions for Android • Anko @nicolas_frankel - Improve your Android-Fu with Kotlin 6
  • 7. KOTLIN Language developed by JetBrains Open Source Compiles to • JVM bytecode • JavaScript (experimental) A "simpler Scala" @nicolas_frankel - Improve your Android-Fu with Kotlin 7
  • 8. KOTLIN Functional and object-oriented Statically typed Null safety No checked exceptions Named & optional arguments Lambdas Extension functions Java compatibility (And more...) @nicolas_frankel - Improve your Android-Fu with Kotlin 8
  • 9. HELLO WORLD! package hello // optional semicolons // namespace-level functions // types on the right // no special syntax for arrays // optional return type fun main(args: Array<String>) { println("Hello, world!") } @nicolas_frankel - Improve your Android-Fu with Kotlin 9
  • 10. SETUP - BUILD.GRADLE buildscript { ext.kotlin_version = '1.0.0-beta-1038' repositories { jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle- plugin:$kotlin_version" } } @nicolas_frankel - Improve your Android-Fu with Kotlin 10
  • 11. SETUP – APP/BUILD.GRADLE apply plugin: 'kotlin-android' android { sourceSets { main.java.srcDirs += 'src/main/kotlin' test.java.srcDirs += 'src/test/kotlin' } } @nicolas_frankel - Improve your Android-Fu with Kotlin 11
  • 12. SAMPLE CODE public class AddTaskEvent extends AbstractTaskEvent { private final List list; public AddTaskEvent(Task task, List list) { super(task); this.list = list; } public List getList() { return list; } } @nicolas_frankel - Improve your Android-Fu with Kotlin 12
  • 13. PAIN POINTS Verbose! • Not specific to Android • Unfortunately Java @nicolas_frankel - Improve your Android-Fu with Kotlin 13
  • 14. KOTLIN SOLUTION class AddTaskEvent(task: Task, val list: List) : AbstractTaskEvent(task) @nicolas_frankel - Improve your Android-Fu with Kotlin 14
  • 15. SAMPLE CODE public class KeyboardDisplay { public void show(Activity a) { InputMethodManager imm = (InputMethodManager) a.getSystemService(INPUT_METHOD_SERVICE); imm.toggleSoftInput(SHOW_FORCED, 0); } public void hide(Activity a) { InputMethodManager imm = (InputMethodManager) a.getSystemService(INPUT_METHOD_SERVICE); imm.toggleSoftInput(HIDE_IMPLICIT_ONLY, 0); } } @nicolas_frankel - Improve your Android-Fu with Kotlin 15
  • 16. PAIN POINTS Artificial grouping Utility class • No real Object, nor state @nicolas_frankel - Improve your Android-Fu with Kotlin 16
  • 17. KOTLIN SOLUTION fun show(a: Activity) { val imm = a.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager imm.toggleSoftInput(SHOW_FORCED, 0) } fun hide(a: Activity) { val imm = a.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager imm.toggleSoftInput(HIDE_IMPLICIT_ONLY, 0) } @nicolas_frankel - Improve your Android-Fu with Kotlin 17
  • 18. SAMPLE CODE SQLiteDatabase db = getReadableDatabase(); db.query(TASK_TABLE, new String[] { T_ID_COL, T_NAME_COL }, null, null, null, null, T_PRIO_COL); @nicolas_frankel - Improve your Android-Fu with Kotlin 18
  • 19. PAIN POINTS @nicolas_frankel - Improve your Android-Fu with Kotlin 19 Really, pass all those null values? Create local variable for ease of use
  • 20. KOTLIN SOLUTION – PART 1 fun SQLiteDatabase.query(table:String, columns:Array<String>, selection:String? = null, selectionArgs:Array<String>? = null, groupBy:String? = null, having:String? = null, orderBy:String? = null): Cursor { return query(table, columns, selection, selectionArgs, groupBy, having, orderBy) } @nicolas_frankel - Improve your Android-Fu with Kotlin 20
  • 21. KOTLIN SOLUTION – PART 2 readableDatabase.query(TASK_TABLE, arrayOf(T_ID_COL, T_NAME_COL), orderBy = T_PRIO_COL) @nicolas_frankel - Improve your Android-Fu with Kotlin 21
  • 22. KOTLIN LIBRARY Standard API for the language @nicolas_frankel - Improve your Android-Fu with Kotlin 22
  • 23. SETUP – APP/BUILD.GRADLE dependencies { compile "org.jetbrains.kotlin:kotlin- stdlib:$kotlin_version" } @nicolas_frankel - Improve your Android-Fu with Kotlin 23
  • 24. SAMPLE CODE public class DisplayMetricsGetter { public DisplayMetrics getFrom(Context c) { WindowManager wm = (WindowManager) c.getSystemService(WINDOW_SERVICE); DisplayMetrics metrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(metrics); return metrics; } } @nicolas_frankel - Improve your Android-Fu with Kotlin 24
  • 25. PAIN POINTS Utility class Cannot return the object directly • Have to create a local variable @nicolas_frankel - Improve your Android-Fu with Kotlin 25
  • 26. KOTLIN SOLUTION fun getFrom(c: Context): DisplayMetrics { val wm = c.getSystemService(Context.WINDOW_SERVICE) as WindowManager val metrics = DisplayMetrics() wm.defaultDisplay.getMetrics(metrics) return metrics } @nicolas_frankel - Improve your Android-Fu with Kotlin 26
  • 27. KOTLIN SOLUTION fun getFrom(c: Context): DisplayMetrics { val wm = c.getSystemService(Context.WINDOW_SERVICE) as WindowManager return DisplayMetrics().apply { wm.defaultDisplay.getMetrics(this) } } @nicolas_frankel - Improve your Android-Fu with Kotlin 27
  • 28. KOTLIN EXTENSIONS FOR ANDROID Plugin for the Kotlin compiler Provide a "synthetic property" for each widget in a layout @nicolas_frankel - Improve your Android-Fu with Kotlin 28
  • 29. SETUP – APP/BUILD.GRADLE buildscript { repositories { jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin- android-extensions:$kotlin_version" } } @nicolas_frankel - Improve your Android-Fu with Kotlin 29
  • 30. SAMPLE CODE public class AddActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.task_add_item); View imageView = findViewById(R.id.new_task_img); imageView.setOnClickListener(...); } } @nicolas_frankel - Improve your Android-Fu with Kotlin 30
  • 31. SAMPLE CODE – WITH BUTTERKNIFE public class AddActivity extends AppCompatActivity { @Bind(R.id.new_task_img) View imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.task_add_item); ButterKnife.bind(this); imageView.setOnClickListener(...); } } @nicolas_frankel - Improve your Android-Fu with Kotlin 31
  • 32. PAIN POINTS Do I have to detail??? @nicolas_frankel - Improve your Android-Fu with Kotlin 32
  • 33. KOTLINX SOLUTION import kotlinx.android.synthetic.task_add_item.new_task_img class AddTaskActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.task_add_item) new_task_img.setOnClickListener(...) } } @nicolas_frankel - Improve your Android-Fu with Kotlin 33
  • 34. ANKO Kotlin library for Android Mostly about replacing XML with fluent DSL for GUI But a lot of other niceties @nicolas_frankel - Improve your Android-Fu with Kotlin 34
  • 35. CODE SAMPLE public class AddAlarmClickListener implements View.OnClickListener { @Override public void onClick(View view) { View rootView = view.getRootView(); ViewFlipper flip = (ViewFlipper) rootView.findViewById(R.id.new_task_alarm_flip); flip.setDisplayedChild(1); } } @nicolas_frankel - Improve your Android-Fu with Kotlin 35
  • 36. PAIN POINTS Cast Setter (?) @nicolas_frankel - Improve your Android-Fu with Kotlin 36
  • 37. ANKO SOLUTION import org.jetbrains.anko.* class AddAlarmClickListener: View.OnClickListener { override fun onClick(view: View) { val parent:View = view.rootView val flip = parent.find<ViewFlipper>(R.id.new_task_alarm_flip) flip.displayedChild = 1 } } @nicolas_frankel - Improve your Android-Fu with Kotlin 37
  • 38. CODE SAMPLE fun show(a: Activity) { val imm = a.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager imm.toggleSoftInput(SHOW_FORCED, 0) } fun hide(a: Activity) { val imm = a.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager imm.toggleSoftInput(HIDE_IMPLICIT_ONLY, 0) } @nicolas_frankel - Improve your Android-Fu with Kotlin 38
  • 39. PAIN POINTS Map-based API Cast @nicolas_frankel - Improve your Android-Fu with Kotlin 39
  • 41. CODE SAMPLE AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setMessage("New list name"); EditText editText = new EditText(activity); editText.setId( android.support.v7.appcompat.R.id.select_dialog_listview); String listName = global.getList().getName(); editText.setText(listName, NORMAL); editText.selectAll(); builder.setView(editText); builder.setPositiveButton("OK", editListNameListener); builder.setNegativeButton("Cancel", (dialog, which) -> { dialog.cancel(); }); AlertDialog dialog = builder.create(); dialog.show(); @nicolas_frankel - Improve your Android-Fu with Kotlin 41
  • 42. PAIN POINTS Verbose +++ Not structured @nicolas_frankel - Improve your Android-Fu with Kotlin 42
  • 43. ANKO SOLUTION view.context.alert('New list name') { builder.setPositiveButton('OK', editListNameListener) negativeButton('Cancel') { cancel() } customView { editText(global.list.name) { id = an.sup.v7.appcompat.R.id.select_dialog_listview }.selectAll() } }.show() @nicolas_frankel - Improve your Android-Fu with Kotlin 43
  • 44. FINAL STACK Dagger 2 Butterknife  Kotlin ext. Retro-lambda  Kotlin Streams  Kotlin Green Robot’s EventBus Picasso @nicolas_frankel - Improve your Android-Fu with Kotlin 44
  • 45. MIGRATION TACTICS @nicolas_frankel - Improve your Android-Fu with Kotlin 45 Start with standard classes • Then with Android-dependent classes Use Android Studio provided migration tool Take a class • Migrate to Kotlin extension • Migrate to Anko • After each single change, test! Repeat
  • 46. PITFALL @nicolas_frankel - Improve your Android-Fu with Kotlin 46 Null-able types
  • 47. NULL-ABLE VS. NON NULL-ABLE TYPES @nicolas_frankel - Improve your Android-Fu with Kotlin 47 Different type whether value can be null or not • T: cannot be null • T?: can be null
  • 48. NULL-ABLE VS. NON NULL-ABLE TYPES @nicolas_frankel - Improve your Android-Fu with Kotlin 48 Parameter types should use the right kind • Know your API • Or read the docs • Or be conservative
  • 49. MY EXPERIENCE @nicolas_frankel - Improve your Android-Fu with Kotlin 49 More expressive Higher-level abstractions One single class I couldn’t migrate • Dagger 2 module
  • 50. Q&A @nicolas_frankel - Improve your Android-Fu with Kotlin 50 http://blog.frankel.ch/ @nicolas_frankel http://frankel.in/