GithubHelp home page GithubHelp logo

bhanditz / devfestahm2017 Goto Github PK

View Code? Open in Web Editor NEW

This project forked from ravidsrk/devfestahm2017

0.0 2.0 0.0 1.96 MB

Slides and references used for "Pragmatic Kotlin for Android Developers" talk at #DevfestAhm

License: MIT License

Kotlin 100.00%

devfestahm2017's Introduction

45%, inline, right

Pragmatic Kotlin ❤️

Practical Tips to migrate your Android App to Kotlin
By Ravindra Kumar @ravidsrk

About Me


Agenda

  • Talk Intro
  • About Me
  • Agenda - In Progress
  • Steps to Convert
  • Common converter Issues
  • Takeaways
  • Eliminate all !! from your Kotlin code

Steps to Convert

Once you learn basics syntax of Kotlin

  1. Convert files, one by one, via "⌥⇧⌘K", make sure tests still pass
  2. Go over the Kotlin files and make them more idiomatic.
  3. Repeat step 2 until you convert all the files.
  4. Ship it.

Common Converter Issues

  • TypeCasting for the sake of Interoperability.
  • Companion will add extra layer.
  • If java method starting with getX(), converter looks for property with the name X.
  • Generics are hard to get it right on the first go.
  • No argument captor.
  • git diff If two developers are working on same java file and one guy converts it to Kotlin, it will be rework.

TypeCasting for the sake of Interoperability

Kotlin is not Interoperable right away, but you need to do a lot of work around to make it Interoperable

Here is the Java class:

public class DemoFragment extends BaseFragment implements DemoView {
  
    @Override
    public void displayMessageFromApi(String apiMessage) {
      ...
    }
}

// Kotlin class
class DemoResponse {
    @SerializedName("message") var message: String? = null
}

// Typecasting to String
mainView?.displayMessageFromApi(demoResponse.message as String)

Companion will add extra layer

Here is Java class:

public class DetailActivity extends BaseActivity implements DetailMvpView{
    public static final String EXTRA_POKEMON_NAME = "EXTRA_POKEMON_NAME";

    public static Intent getStartIntent(Context context, String pokemonName) {
        Intent intent = new Intent(context, DetailActivity.class);
        intent.putExtra(EXTRA_POKEMON_NAME, pokemonName);
        return intent;
    }
}

Converted Kotlin class:

class DetailActivity : BaseActivity(), DetailMvpView {
    companion object {
        val EXTRA_POKEMON_NAME = "EXTRA_POKEMON_NAME"

        fun getStartIntent(context: Context, pokemonName: String): Intent {
            val intent = Intent(context, DetailActivity::class.java)
            intent.putExtra(EXTRA_POKEMON_NAME, pokemonName)
            return intent
        }
    }
}

public class MainActivity extends BaseActivity implements MainMvpView {
  private void pokemonClicked(Pokemon pokemon) {
      startActivity(DetailActivity.Companion.getStartIntent(this, pokemon))    
  }
}

public class MainActivity extends BaseActivity implements MainMvpView {
  private void pokemonClicked(Pokemon pokemon) {
      startActivity(DetailActivity.Companion.getStartIntent(this, pokemon))    
  }
}

Remember: *you do not need to stress about migrating the entire codebase.


Method names starting with get

Here is the Java class:

public interface DemoService {
    @GET("posts")
    Observable<PostResponse> getDemoResponse();

    @GET("categories")
    Observable<CategoryResponse> getDemoResponse2();
}

interface DemoService {
    @get:GET("posts")
    val demoResponse: Observable<PostResponse>
    
    @get:GET("categories")
    val demoResponse2: Observable<CategotyResponse>
}

Expecting methods demoResponse and demoResponse2, They are being interpreted as getter methods, this will cause lots of issues.


No ArgumentCaptor

If you are using Mockito’s ArgumentCaptor you will most probably get following error

java.lang.IllegalStateException: classCaptor.capture() must not be null

The return value of classCaptor.capture() is null, but the signature of SomeClass#someMethod(Class, Boolean) does not allow a null argument.

mockito-kotlin library provides supporting functions to solve this problem


Key Takeaways

  • annotationProcessor must be replaced by kapt in build.gradle
  • Configure tests to mock final classes
  • If you are using android data-binding, include:
kapt com.android.databinding:compiler:3.0.0
  • @JvmField to rescue while using ButterKnife @InjectView and Espresso @Rule

Eliminate all !! from your Kotlin code

  1. Use val instead of var

  2. Use lateinit

  3. Use let function

  4. User Elivis operator


Use val instead of var

  • Kotlin makes you think about immutability on the language level and that’s great.
  • var and val mean "writable" and "read-only"
  • If you use them as immutables, you don’t have to care about nullability.

Use lateinit

private var adapter: RecyclerAdapter<Droids>? = null

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   mAdapter = RecyclerAdapter(R.layout.item_droid)
}

fun updateTransactions() {
   adapter!!.notifyDataSetChanged()
}

private lateinit var adapter: RecyclerAdapter<Droids>

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   mAdapter = RecyclerAdapter(R.layout.item_droid)
}

fun updateTransactions() {
   adapter?.notifyDataSetChanged()
}

Use let function

private var photoUrl: String? = null

fun uploadClicked() {
    if (photoUrl != null) {
        uploadPhoto(photoUrl!!)
    }
}

private var photoUrl: String? = null

fun uploadClicked() {
	photoUrl?.let { uploadPhoto(it) }
}

User Elivis operator

Elvis operator is great when you have a fallback value for the null case. So you can replace this:

fun getUserName(): String {
   if (mUserName != null) {
       return mUserName!!
   } else {
       return "Anonymous"
   }
}

Elvis operator is great when you have a fallback value for the null case. So you can replace this:

fun getUserName(): String {
   return mUserName ?: "Anonymous"
}

Final tip

Don’t try to learn the whole language at once


Questions?


65%, original

Thank You


Android Testing Guide

right,original

devfestahm2017's People

Contributors

ravidsrk avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.