kotlin a problem solver - gdd extended pune
TRANSCRIPT
Kotlin for AndroidA Real Problem Solver
Hardik Trivedi
Source : https://developers.google.com/events/gdd-india/
Hardik Trivedi● I am a computer program writer
● Works at Globant, Pune, IN
● An active community speaker
● Co-author of a book "Kotlin Blueprints"
● I love writing tech blogs
● I am mentor for college graduates and
professionals and consultant to companies
About MeEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Exciting talk and training from Sean @ GDDIndiaEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Day 1: Testing Out Kotlin
Testing is a great way to learn Kotlin, write readable tests, and introduce your development team to the power of Kotlin. Learn how to use Kotlin through a deep dive into writing tests.
Day 2: Taking Advantage of Kotlin in Your Android App
Hands-on experience building Android apps using Android Studio in the Kotlin language.Checkout code at https://goo.gl/SyGJ1i
Sean McQuillanAndroid Developer
Why Kotlin?Email: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
It’s a Modern
● Type Inference
● First class functions
● Abstraction
● Lambdas
● Extensions
● Coroutines
Why Kotlin?Email: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
It’s built for Industry
● Not only expressive but keeps Performance in mind
● Readable
● Easy to write scalable code
● It’s targeting JVM, mobile and browsers
● Great tooling support from JetBrains
Why Kotlin?Email: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
It’s easy to Use
● Interoperability
● Learn in a day
● No surprises
Kotlin announcementsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
● Kotlin 1.2 is out. It has ability to reuse code between JVM and JavaScript
● Kotlin/Native 0.5 is out and it has power calling Kotlin from Swift, C and LLVM 5
● Added a style guide https://android.github.io/kotlin-guides/style.html It has all
the standards Google has used to code in Kotlin
● Added Kotlin/Native support to CLion
● Jetbrains release official Kotlin wrappers to work with React.JS
● Android Lint has support to Kotlin. You can also write custom lint rules for Kotlin.
KotlinBasics.inc(){ }
Source : https://developers.google.com/events/gdd-india/
Extension FunctionEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
val str = "GGDD Extendedd"
fun String.removeFirstLastChar(): String {
return this.substring(1, this.length - 1)
}
str.removeFirstLastChar()// Output is GDD Extended
Extension FunctionEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
fun View.visible() {
this.visibility = View.VISIBLE
}
fun View.gone() {
this.visibility = View.GONE
}
button.visible()
textView.gone()
Delegated PropertiesEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Properties usually contains the direct corresponding value
But Kotlin allows you to delegate some task/behaviour to the properties if managed
properly.
● lazy properties: the value gets computed only upon first access;
● observable properties: listeners get notified about changes to this property;
● storing properties in a map, instead of a separate field for each property.
Delegated Properties - VetoableEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
class Veto {
var value: String by Delegates.vetoable("String")
{ prop, old, new -> new.contains("GDD") }
}
val veto = Veto()
veto.value = "DevFest"
println(veto.value) // Output String
veto.value="GDD Extended Pune"
println(veto.value) // Output GDD Extended Pune
Semantic ValidationEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Many times we do parameter validation thorough and aggressivelystatic String join(String sep, List<String> strings) {
if (sep == null) throw new NullPointerException("sep == null");
if (sep.length() < 2) {
throw new IllegalArgumentException("sep.length() < 2");
}
if (strings == null) throw new NullPointerException("strings == null");
...
}
Semantic ValidationEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
● With Guava like libraries you can avoid those null checks and manage the pre
conditions gracefully.
● But you don’t add guava for to use only one feature.
● Kotlin avoids nullability by default and it has functions for semantic validations.
fun join(sep: String, strings: List<String>): String {
require(sep.length < 2) { "sep.length() < 2" }
...
}
Let functionEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Java
String data=null;
if(data!=null) {
// Do something
}
Kotlin
var data: String? = null
data?.let {
// it == data always not null and read only once
}
Let functionEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
class Concurrent {
@Volatile var data: String? = null
fun doSomething() {
data?.let {
//data always not null and read only once
}
}
}
Higher-order functionEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
A higher-order function is a function that takes functions as parameters, or returns a
function.
fun logExecution(func: () -> Unit) {
Log.d("tag", "before executing func")
func()
Log.d("tag", "after executing func")
}
logExecution({ yourFunction() })
Wow momentsSee Kotlin in Action !!!{ }
Source : https://developers.google.com/events/gdd-india/
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
// Possible only if it's Java 8
public interface InterfaceA {
default void defaultMethod(){
System.out.println("Interface A
default method");
}
}
interface ToolbarManager {
fun initToolbar() {
toolbar.inflateMenu(R.menu.main_menu)
toolbar.setOnMenuItemClickListener {
// Your code
true
}
}
}
Java Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Button clickButton = (Button)
findViewById(R.id.clickButton);
clickButton.setOnClickListener( new
OnClickListener() {
@Override
public void onClick(View v) {
***Do what you want with the
click here***
}
});
import
kotlinx.android.synthetic.main.activity_
detail.*
clickButton.setOnClickListener {
***Do what you want with the click
here***
}
Java Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
private String readInputStream(InputStream is) throws
Exception {
String line = null;
StringBuilder sb = new StringBuilder();
BufferedReader bufferedReader = new
BufferedReader(new InputStreamReader(is));
while ((line = bufferedReader.readLine()) != null)
{
sb.append(line);
}
bufferedReader.close();
return sb.toString();
}
val inputAsString =
is.bufferedReader().use
{ it.readText() }
// defaults to UTF-8
Java Kotlin
Wow moments
public class MySingleton {
private static MySingleton myObj;
private MySingleton(){
}
public static MySingleton getInstance(){
if(myObj == null){
myObj = new MySingleton();
}
return myObj;
}
}
object MySingleton {
var num: Int = 0
fun domeSomeThing() {
println("Kotlin is awesome!!!")
}
}
Java Kotlin
Email: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
SharedPreferences sharedpreferences =
getSharedPreferences(mypreference,
Context.MODE_PRIVATE);
email.setText(sharedpreferences.getStrin
g(Email, ""));
SharedPreferences.Editor editor =
sharedpreferences.edit();
editor.putString("email",
editor.apply();
private var email: String by
DelegatedPreference(this, "email", "")
email="[email protected]"
txtEmail.text=email
Java Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Movie movie = moviesList.get(position);
holder.title.setText(movie.getTitle());
holder.genre.setText(movie.getGenre());
holder.year.setText(movie.getYear());
Movie movie = moviesList[position]
with(movie) {
holder.title.text=title
holder.genre.text=genre
holder.year.text=year
}
Java Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
private class GetWeatherTask extends
AsyncTask<String, Void, Forecast> {
protected Forecast doInBackground(String
zipCode) {
return WeatherAPI().execute(zipCode);
}
protected void onPostExecute(Forecast
result) {
showData(result);
}
}
new GetWeatherTask().execute(380015);
fun loadWeatherData() = async(UI) {
val waiter = bg {
WeatherApi(zipCode).execute() }
showData(waiter.await())
}
Java Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Intent intent = Intent(this,SomeOtherActivity.class)
intent.putExtra("id", 5)
intent.setFlag(Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(intent)
startActivity(intentFor<SomeOtherActivity>("id" to 5).singleTop())
Java
Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
return inflater.inflate(R.layout.fragment_update_info, container, false);
}
fun ViewGroup.inflate(@LayoutRes layoutRes: Int, attachToRoot: Boolean = false):
View {
return LayoutInflater.from(context).inflate(layoutRes, this, attachToRoot)
}
parent.inflate(R.layout.my_layout)
parent.inflate(R.layout.my_layout, true)
Java
Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Picasso.with(context).load(R.mipmap.ic_launcher).into(imageView);
fun ImageView.loadUrl(url: String) {
Picasso.with(context).load(url).into(this)
}
imageView.loadUrl("http://....")
Java
Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
getSupportFragmentManager().beginTransaction()
.add(R.id.container,DataFragment.newInstance(), "detail")
.addToBackStack()
.commit();
fun AppCompatActivity.addFragment(fragment: Fragment, frameId: Int, backStackTag: String? =
null) {
supportFragmentManager.inTransaction {
add(frameId, fragment)
backStackTag?.let { addToBackStack(fragment.javaClass.name) }
}
}
addFragment(DataFragment.newInstance(), R.id.container, "detail")
Java
Kotlin
Snackbar snackbar = Snackbar
.make(coordinatorLayout, "Welcome to GDD", Snackbar.LENGTH_LONG);
snackbar.show();
inline fun View.snack(message: String, length: Int = Snackbar.LENGTH_LONG) {
val snack = Snackbar.make(this, message, length)
snack.show()
}
view.snack("Welcome to GDD")
view.snack("Welcome to GDD", Snackbar.LENGTH_SHORT)
Java
Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
class Address {
String name = ...;
String street = ...;
String city = ...;
String state = ...;
String zip = ...;
}
Address address = new Address();
System.out.println(address.getName());
System.out.println(address.getStreet());
class Address {
var name: String = ...
var street: String = ...
var city: String = ...
var state: String? = ...
var zip: String = ...
}
val address = Address()
println(address.name)
println(address.street)
Java Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
doSomething(position);
}
}, 250);
scrollView.postDelayed({
onTabPageSelected(position) }, 200)
Java Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Email: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
List<User> users = api.getUsers();
List<User> activeUsers = new
ArrayList<>();
for (User user : users) {
if (user.isActive()) {
activeUsers.add(user);
}
}
adapter.setUsers(activeUsers);
val users = api.getUsers()
val activeUsersNames = items.filter {
it.active
}
adapter.setUsers(activeUsers)
Java Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Email: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
private class GetWeatherTask extends
AsyncTask<String, Void, Forecast> {
protected Forecast doInBackground(String
zipCode) {
return WeatherAPI().execute(zipCode);
}
protected void onPostExecute(Forecast
result) {
showData(result);
}
}
new GetWeatherTask().execute(380015);
fun loadWeatherData() = async(UI) {
val waiter = bg {
WeatherApi(zipCode).execute() }
showData(waiter.await())
}
Java Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
@Override
public boolean onOptionsItemSelected(MenuItem
item) {
switch (item.getItemId()) {
case R.id.new_game:
newGame();
return true;
case R.id.help:
showHelp();
return true;
default:
return
super.onOptionsItemSelected(item);
}
}
override fun onOptionsItemSelected(item:
MenuItem) = when (item.itemId) {
R.id.new_game -> consume {
navigateToNewGame() }
R.id.help -> drawer.consume {
navigateToHelp() }
else -> super.onOptionsItemSelected(item)
}
inline fun consume(f: () -> Unit): Boolean {
f()
return true
}
Java Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
if (obj instanceof TextArea) {
((TextArea)obj).append("some data");
} else {
// Do something
}
if (view is TextArea) {
view.append("Kotlin is awesome!")
} else {
// Do something
}
Java Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Email: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
textView {
id = R.id.errorView
textColor = ContextCompat.getColor(ctx, R.color.red_error)
text = string(R.string.error_view_login_text)
textSize = 14f
visibility = View.GONE
}
textView {
lparams(width = matchParent, height = wrapContent) {
gravity = Gravity.CENTER
leftMargin = dip(16)
rightMargin = dip(16)
}
}
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Email: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
// Showing Alerts
alert("Hi, are you enjoying the Kotlin talk?") {
yesButton { toast("Yes :)") }
noButton {}
}.show()
// Showing progress dialog
val dialog = progressDialog(message = "Please wait a bit…", title = "Fetching data")
// Showing SnackBar
snackbar(view, "Hi there!")
snackbar(view, R.string.message)
longSnackbar(view, "Wow, such duration")
snackbar(view, "Action, reaction", "Click me!") { doStuff() }
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
anObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(new Func1<String, List<String>>() {
@Override
public List<String> call(String s) {
...
}
})
.subscribe(new Observer<List<String>>() {
...
anObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread(
))
.map { }
.doOnNext{ }
.subscribe { data -> }
Java Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
@Test
public void
testSomethingWorksAsExpected() {
Assert.assertTrue(false);
}
Java@Test fun `test something works as
expected`() {
Assert.assertTrue(false)
}
Also
import org.mockito.Mockito.`when` as
_when
Kotlin
Wow momentsEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Email: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
JVM Native
iOS, etc.
JS
Kotlin
Android Spring, etc.
Future of KotlinEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
ReferencesEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
● Kotlin official website
● Android official website
● Git repo from Developer Advocate at JetBrains
● Android Pub
● Antonio Leiva's blog
● Bob’s blog
● Anko Github page
● Sample Android app using Kotlin
ReferencesEmail: [email protected] Follow: @MrHardikTrivedi Visit: trivedihardik.wordpress.com
Thank You@MrHardikTrivedi{ }
Source : https://developers.google.com/events/gdd-india/