SlideShare a Scribd company logo
Building a DRYer Android App with
Kotlin
by Boonya Kitpitak
DRY
➔ Don’t Repeat Yourself
➔ Reducing Repetition
WET
➔ Waste Everyone Time
➔ We Enjoy Typing
➔ Write Everything Twice
(or more)
Building a DRYer Android App with Kotlin
Building a DRYer Android App with Kotlin
Avoid repeating yourself by using Higher
Order Function and Extension function.
Outline
➔ Higher order function
➔ Extension function
➔ Higher order function + Extension function
➔ Conclusion
Higher Order Function
“A higher-order function is a function that takes functions
as parameters, or returns a function.”
fun higherOrderFunction(block: () -> Unit) {
…
block()
…
}
Parameter Return value
Example : Suppose I want to measure the execution time of a function
		val	startTime	=	System.currentTimeMillis()	
				printSpeakerList()	
				val	endTime	=	System.currentTimeMillis()	
				println("Executed	in	${endTime	-	startTime}ms")	
*https://hackernoon.com/a-practical-use-for-higher-order-functions-in-kotlin-7ff89cebf6fd
What if I want to measure the execution time of other lines of code ?
val	startTime	=	System.currentTimeMillis()	
		printSpeakerList()	
		val	endTime	=	System.currentTimeMillis()	
		println("Executed	in	${endTime	-	startTime}ms")
		val	startTime	=	System.currentTimeMillis()	
			printAudienceList()	
			val	endTime	=	System.currentTimeMillis()	
			println("Executed	in	${endTime	-	startTime}ms")	
		val	startTime	=	System.currentTimeMillis()	
			printOrganizerList()	
				val	endTime	=	System.currentTimeMillis()	
				println("Executed	in	${endTime	-	startTime}ms")
Make it DRY: Define a higher order function that accept function
		val	startTime	=	System.currentTimeMillis()	
		
			val	endTime	=	System.currentTimeMillis()	
			println("Executed	in	${endTime	-	startTime}ms")	
				
				
fun	printExecutionTime(	block:	()	->	Unit	)	{	
										
						
			
}	
block()
				
//Operation	your	want	to	measure
printExecutionTime	({	
						printOrganizerList()	
		})	
Using our higher order function
	printExecutionTime	({	
						printAudienceList()	
		})	
	printExecutionTime	({	
						printSpeakerList()	
		})	
fun	printExecutionTime(block:	()	->	Unit)	{	
			val	startTime	=	System.currentTimeMillis()	
			block()	
			val	endTime	=	System.currentTimeMillis()	
			println("Executed	in	${endTime	-	startTime}ms")	
}	
Higher Order Function
Lambda
Higher Order Function != Lambda
		printExecutionTime	({	
				printAudienceList()	
})
Setting Status bar color : Only available after Lollipop
			if	(Build.VERSION.SDK_INT	>=	Build.VERSION_CODES.LOLLIPOP)	{	
								window.setStatusBarColor(Color.BLACK)	
			}
			if	(Build.VERSION.SDK_INT	>=	Build.VERSION_CODES.LOLLIPOP)	{	
								window.setStatusBarColor(Color.BLACK)	
			}
			if	(Build.VERSION.SDK_INT	>=	Build.VERSION_CODES.LOLLIPOP)	{	
								window.setStatusBarColor(Color.BLACK)				}
* https://www.androidauthority.com/android-m-dark-status-bar-icons-613241/
blocks of code that are only executed if the version is Lollipop or newer:
supportsLollipop	({	
			window.setStatusBarColor(Color.BLACK)	
})	
inline	fun	supportsLollipop(block:	()	->	Unit)	{	
			if	(Build.VERSION.SDK_INT	>=	Build.VERSION_CODES.LOLLIPOP)	{	
							block()	
			}	
}
supportsLollipop	{	
			window.setStatusBarColor(Color.BLACK)	
}
Also work when checking Build Variant
inline	fun	debug(block:()	->	Unit)	{	
			if	(BuildConfig.DEBUG)	{	
							block()	
			}	
}	
debug	{	
			//	do	something	
}
Extension Function
“Ability to extend a class with new functionality without
having to inherit from the class or use any type of design
pattern.”
Extension function example: String to uri
		
	val	uri1	=	Uri.parse(“https://stackoverflow.com”)	
	val	uri2	=	Uri.parse(“https://youtube.com”)	
/**	
	*	Creates	a	Uri	from	the	given	encoded	URI	string.	
	*	
	*	@see	Uri.parse	
	*/	
fun	String.toUri():	Uri	=	Uri.parse(this)	
	val	uri1	=	“https://stackoverflow.com”.toUri()	
	val	uri2	=	“https://youtube.com”.toUri()
Extension function example: Create toast in Fragment
Toast.makeText(context, "Hello MobileConf 2018", Toast.LENGTH_LONG).show()
Toast.makeText(context, "Hello MobileConf 2018", Toast.LENGTH_SHORT).show()
fun Fragment.longToast(text: String) {
Toast.makeText(context, text, Toast.LENGTH_LONG).show()
}
fun Fragment.shortToast(text: String) {
Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
}
longToast("Hello MobileConf 2018")
shortToast( "Hello MobileConf 2018")
Extension Function + Higher Order Function
“ Let’s make it even shorter ”
Extension function example: Edit SharePreference
sharedPreferences.edit()	
								.putString(“event_name”,	“MobileConf2018”)	
								.apply()	
sharedPreferences.edit {
putString(“event_name”, “MobileConf2018”)
}
inline fun SharedPreferences.edit(
action: SharedPreferences.Editor.() -> Unit
) {
val editor = edit()
action(editor)
editor.apply()
}
Let’s make Retrofit network call DRYer
val	call	=	api.getSpeakerList()	
call.enqueue(object	:	Callback<List<Speaker>>	{	
			override	fun	onResponse	(call:Call<List<Speaker>>?,	response:Response<List<Speaker>>?)	{	
							response?.let	{	
											if	(response.isSuccessful)	{	
															processSpeakerList(it)	
											}	else	{	
															handleError()	
											}	
							}	
			}	
			override	fun	onFailure(call:	Call<List<Speaker>>?,	t:	Throwable?)	{	
							handleError()	
							logErrorToFabric()	
							logErrorToFirebase()	
			}	
})
inline	fun	<T>	retrofit2.Call	<T>.enqueue(crossinline	successHandler	:	(T?)	->	Unit,	
																																	crossinline	failureHandler:	()	->	Unit)	=	
							this.enqueue(object	:	Callback<T>	{	
															override	fun	onResponse(call:	Call<T>?,	response:	Response<T>?)	{	
																			response?.let	{	
																							if	(response.isSuccessful)	{	
																											successHandler(it.body())	
																							}	else	{	
																											failureHandler()	
																							}	
																			}	
															}	
															override	fun	onFailure(call:	Call<T>?,	t:	Throwable?)	{	
																							
																					failureHandler()	
																					logErrorToFabric()	
																					logErrorToFirebase()	
																}	
											}	
							})	
}
Declaring extension function
val	call	=	api.getSpeakerList()	
call.enqueue(object	:	Callback<List<Speaker>>	{	
			override	fun	onResponse(call:Call<List<Speaker>>?,	response:Response<List<Speaker>>?){	
							response?.let	{	
											if	(response.isSuccessful)	{	
															processSpeakerList(it)	
											}	else	{	
															handleError()	
											}	
							}	
			}	
			override	fun	onFailure(call:	Call<List<Speaker>>?,	t:	Throwable?)	{	
							handleError()	
							logErrorToFabric()	
							logErrorToFirebase()	
			}	
})	
call.enqueue({	
			processSpeakerList(it)	
},	{	
			handleError()	
})
Where should we declare extension function ?
Extension function should be declare as top-level function ( function that
locate outside of the class )
Inline function ?
An inline function will be substituted by its code during compilation, instead of
doing the real call to a function. It will reduce memory allocations and runtime
overhead in some situations.
inline	fun	debug(block:()	->	Unit)	{	
			if	(BuildConfig.DEBUG)	{	
							block()	
			}	
}
inline	fun	supportsLollipop(block:	()	->	Unit)	{	
			if	(Build.VERSION.SDK_INT	>=	Build.VERSION_CODES.LOLLIPOP)	{	
							block()	
			}	
}
Conclusion
- Higher order function is function that accept or return function
- Extension function can add more functionality to existing class
- They both help make our code DRYer
Q/A
Boonya Kitpitak (Ben)
Android Developer from Oozou
ben@oozou.com
medium.com/@boonya.kitpitak
Thank you.

More Related Content

PDF
Mastering Kotlin Standard Library
PDF
Go Concurrency
PPTX
Web streams
PDF
Golang Channels
PDF
"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)
KEY
Introduction to PiCloud
PDF
Introduction to kotlin coroutines
PDF
Go Containers
Mastering Kotlin Standard Library
Go Concurrency
Web streams
Golang Channels
"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)
Introduction to PiCloud
Introduction to kotlin coroutines
Go Containers

What's hot (20)

DOCX
7th lab
PDF
Something about Golang
PDF
Understanding greenlet
PDF
PyCon lightning talk on my Toro module for Tornado
PPTX
The State of JavaScript (2015)
PPTX
RuntimeUnitTestToolkit for Unity(English)
PDF
«Продакшн в Kotlin DSL» Сергей Рыбалкин
PDF
Python meetup: coroutines, event loops, and non-blocking I/O
PDF
The async/await concurrency pattern in Golang
PPTX
All you need to know about the JavaScript event loop
PDF
Python Coroutines, Present and Future
PDF
Goroutines and Channels in practice
PDF
Paradigma FP y OOP usando técnicas avanzadas de Programación | Programacion A...
TXT
PDF
The Ring programming language version 1.6 book - Part 25 of 189
PDF
PyParis2017 / Function-as-a-service - a pythonic perspective on severless com...
PDF
Goの時刻に関するテスト
PDF
The Ring programming language version 1.5.4 book - Part 40 of 185
KEY
W3C HTML5 KIG-How to write low garbage real-time javascript
KEY
Generating and Analyzing Events
7th lab
Something about Golang
Understanding greenlet
PyCon lightning talk on my Toro module for Tornado
The State of JavaScript (2015)
RuntimeUnitTestToolkit for Unity(English)
«Продакшн в Kotlin DSL» Сергей Рыбалкин
Python meetup: coroutines, event loops, and non-blocking I/O
The async/await concurrency pattern in Golang
All you need to know about the JavaScript event loop
Python Coroutines, Present and Future
Goroutines and Channels in practice
Paradigma FP y OOP usando técnicas avanzadas de Programación | Programacion A...
The Ring programming language version 1.6 book - Part 25 of 189
PyParis2017 / Function-as-a-service - a pythonic perspective on severless com...
Goの時刻に関するテスト
The Ring programming language version 1.5.4 book - Part 40 of 185
W3C HTML5 KIG-How to write low garbage real-time javascript
Generating and Analyzing Events
Ad

Similar to Building a DRYer Android App with Kotlin (20)

PDF
What's in Kotlin for us - Alexandre Greschon, MyHeritage
PDF
Kotlin Advanced - Apalon Kotlin Sprint Part 3
PPTX
Building Mobile Apps with Android
PPTX
Android & Kotlin - The code awakens #03
PDF
Idiomatic Kotlin
PDF
Kotlin for android developers whats new
PDF
Adapting clean architecture in android apps
PPTX
從零開始學 Android
PDF
Kotlin for Android Developers - 3
PDF
Kotlin Generation
PPTX
Introduction to kotlin
PDF
Architecture Patterns in Practice with Kotlin. UA Mobile 2017.
PDF
Miracle of std lib
PDF
Kotlin : Advanced Tricks - Ubiratan Soares
PPTX
KotlinForJavaDevelopers-UJUG.pptx
PDF
How to become an Android dev starting from iOS (and vice versa)
PDF
Kotlin talk
PDF
Exploring Koltin on Android
PDF
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
What's in Kotlin for us - Alexandre Greschon, MyHeritage
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Building Mobile Apps with Android
Android & Kotlin - The code awakens #03
Idiomatic Kotlin
Kotlin for android developers whats new
Adapting clean architecture in android apps
從零開始學 Android
Kotlin for Android Developers - 3
Kotlin Generation
Introduction to kotlin
Architecture Patterns in Practice with Kotlin. UA Mobile 2017.
Miracle of std lib
Kotlin : Advanced Tricks - Ubiratan Soares
KotlinForJavaDevelopers-UJUG.pptx
How to become an Android dev starting from iOS (and vice versa)
Kotlin talk
Exploring Koltin on Android
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
Ad

Recently uploaded (20)

DOCX
The AUB Centre for AI in Media Proposal.docx
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PPT
Teaching material agriculture food technology
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
Cloud computing and distributed systems.
PDF
Encapsulation_ Review paper, used for researhc scholars
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
The AUB Centre for AI in Media Proposal.docx
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Teaching material agriculture food technology
Network Security Unit 5.pdf for BCA BBA.
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Understanding_Digital_Forensics_Presentation.pptx
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Spectral efficient network and resource selection model in 5G networks
Review of recent advances in non-invasive hemoglobin estimation
Dropbox Q2 2025 Financial Results & Investor Presentation
Unlocking AI with Model Context Protocol (MCP)
NewMind AI Weekly Chronicles - August'25 Week I
Building Integrated photovoltaic BIPV_UPV.pdf
Per capita expenditure prediction using model stacking based on satellite ima...
Cloud computing and distributed systems.
Encapsulation_ Review paper, used for researhc scholars
“AI and Expert System Decision Support & Business Intelligence Systems”
Programs and apps: productivity, graphics, security and other tools
The Rise and Fall of 3GPP – Time for a Sabbatical?

Building a DRYer Android App with Kotlin