Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin - A parte boa, a parte ruim

Kotlin - A parte boa, a parte ruim

Apresentação no aniversário de 3 anos do GDG-SP.

Repositório: https://github.com/rafaeltoledo/kotlin-sandbox

Rafael Toledo

May 07, 2016
Tweet

More Decks by Rafael Toledo

Other Decks in Programming

Transcript

  1. Kotlin • JVM / Android e JavaScript • Orientada a

    Objetos • Funcional • Estaticamente Tipada • Open Source • Desenvolvida pela JetBrains @_rafaeltoledo
  2. Data Classes public class User { private final String displayName;

    private final String location; public User(String displayName, String location) { this.displayName = displayName; this.location = location; } @_rafaeltoledo
  3. Data Classes public String getDisplayName() { return displayName; } public

    String getLocation() { return location; } } @_rafaeltoledo
  4. Data Classes data class User( val displayName: String, val location:

    String ) Imutabilidade! val = constante var = variável @_rafaeltoledo
  5. Múltiplas Classes por Arquivo // Arquivo Models.kt package net.rafaeltoledo.kotlinsandbox.data data

    class User( val displayName: String, val location: String ) data class BadgeCounts( val bronze: Int, val silver: Int, val gold: Int ) @_rafaeltoledo
  6. Properties var simple: Int? var tipoInferido = 1 val isEmpty:

    Boolean get() = this.size == 0 var valorString: String get() = this.toString() set(value) { splitAndSet(value) } var privateSetter: String = "a" private set var annotatedSetter: Any? = null @Inject set @_rafaeltoledo
  7. Null Safety override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder? {

    // ... } supportActionBar?.title = "Texto" // se não-nulo // ou supportActionBar!!.title = "Texto" // mesmo que nulo @_rafaeltoledo
  8. Funções Inline override fun getItemCount() = items.size get / set

    se tornam properties automagicamente getItemCount() se torna itemCount @_rafaeltoledo
  9. Extensões @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return

    new ViewHolder( LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_list, parent, false)); } @_rafaeltoledo
  10. Extensões fun ViewGroup.inflate(layoutRes: Int, attachToRoot: Boolean = false): View {

    return LayoutInflater.from(context) .inflate(layoutRes, this, attachToRoot) } @_rafaeltoledo
  11. Extensões override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder? { return

    ViewHolder(parent.inflate(R.layout.item_user)) } @_rafaeltoledo
  12. Parâmetros Default fun ViewGroup.inflate(layoutRes: Int, attachToRoot: Boolean = false): View

    { return LayoutInflater.from(context) .inflate(layoutRes, this, attachToRoot) } @_rafaeltoledo
  13. Parâmetros Default fun ViewGroup.inflate(layoutRes: Int, attachToRoot: Boolean = false): View

    { return LayoutInflater.from(context) .inflate(layoutRes, this, attachToRoot) } @_rafaeltoledo
  14. Parâmetros Default fun ViewGroup.inflate(layoutRes: Int, attachToRoot: Boolean = false): View

    { return LayoutInflater.from(context) .inflate(layoutRes, this, attachToRoot) } parent.inflate(R.layout.item_list) parent.inflate(R.layout.item_list, false) // Mesma coisa parent.inflate(R.layout.item_list, true) @_rafaeltoledo
  15. Import Aliases class Interceptor implements com.squareup.okhttp.Interceptor { // ... }

    import com.squareup.okhttp.Interceptor as OkHttpInterceptor class Interceptor : OkHttpInterceptor { // ... } @_rafaeltoledo
  16. Singletons - Java public class Singleton { private static Singleton

    INSTANCE; public static Singleton getInstance() { if (INSTANCE == null) { INSTANCE = new Singleton(); } return INSTANCE; } private Singleton() {} } @_rafaeltoledo
  17. Lambdas public interface Callback { void onFinish(boolean success); } public

    void requestAssincrona(Callback callback) { // ... callback.onFinish(true); } requestAssincrona(new Callback() { @Override public void onFinish(boolean success) { Log.i(TAG, "Resultado: " + success); } }); @_rafaeltoledo
  18. Lambdas – com Retrolambda / Jack & Jill public interface

    Callback { void onFinish(boolean success); } public void requestAssincrona(Callback callback) { // ... callback.onFinish(true); } requestAssincrona(success -> Log.i(TAG, "Resultado: " + success)); @_rafaeltoledo
  19. Lambdas – Kotlin fun requestAssincrona(callback: (Boolean) -> Unit) { //

    ... callback(true) } // Chamada requestAssincrona { success -> Log.i(TAG, "Resultado: $success") } @_rafaeltoledo
  20. Lambdas – Kotlin fun requestAssincrona(callback: (Boolean) -> Unit) { //

    ... callback(true) } // Chamada requestAssincrona { Log.i(TAG, "Resultado: $it") } @_rafaeltoledo
  21. Interpolação de Strings // Java Log.i(TAG, "Resultado: " + success);

    // Kotlin Log.i(TAG, "Resultado: $success") Log.i(TAG, "Resultado: ${1 + 1 == 2}") @_rafaeltoledo
  22. Android Extensions // app/build.gradle apply plugin: 'kotlin-android-extensions' // Arquivo kotlin

    import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) textView.text = "Hello GDG!" } @_rafaeltoledo
  23. Anko – O que é? Biblioteca desenvolvida pela JetBrains Repositório

    repleto de extensões para os mais diversos propósitos no Android DSL para a criação de layouts github.com/kotlin/anko @_rafaeltoledo
  24. Anko - Intents // Normalmente no Android... Intent intent =

    new Intent(context, DetailActivity.class); intent.putExtra("id", 1); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent); // Anko! startActivity( intentFor<DetailActivity>("id" to 1).singleTop()) @_rafaeltoledo
  25. Anko – Mais extensões // Intents makeCall("1406") browse("https://google.com") email("[email protected]", "Assunto",

    "Conteúdo") // Toasts toast("Oi") toast(R.string.oi) longToast("Oi denovo") // Log info("Oi") warn(0) debug("Outro log") @_rafaeltoledo
  26. Anko – DSL verticalLayout { padding = dip(30) editText {

    hint = "Name" textSize = 24f } editText { hint = "Password" textSize = 24f } button("Login") { textSize = 26f } } @_rafaeltoledo
  27. Dex Limit Total methods in app-debug.apk: 34398 (52,49% used) Total

    fields in app-debug.apk: 13999 (21,36% used) Methods remaining in app-debug.apk: 31137 Fields remaining in app-debug.apk: 51536 @_rafaeltoledo
  28. Dex Limit – com Shrinker (plugin 2.x) Total methods in

    app-debug.apk: 15121 (23,07% used) Total fields in app-debug.apk: 7525 (11,48% used) Methods remaining in app-debug.apk: 50414 Fields remaining in app-debug.apk: 58010 @_rafaeltoledo
  29. Parcelable data class User(val nome: String, val email: String) :

    Parcelable { constructor(parcel: Parcel) : this(parcel.readString(), parcel.readString()) override fun writeToParcel(dest: Parcel?, flags: Int) { dest?.writeString(nome) dest?.writeString(email) } override fun describeContents() = 0 companion object { val CREATOR: Parcelable.Creator<User> = object : Parcelable.Creator<User> { override fun createFromParcel(parcel: Parcel): User = User(parcel) override fun newArray(size: Int): Array<User?> = arrayOfNulls(size) } } } @_rafaeltoledo
  30. Testes Instrumentados no Android Studio !!! JUnit version 3.8 or

    later expected: java.lang.RuntimeException: Stub! @_rafaeltoledo Funcionando no Android Studio 2.x!
  31. Outras coisas Ausência de linters Tempo de build maior Cobertura

    de código para CI Ofuscação? @_rafaeltoledo
  32. É a hora de converter todos os meus apps? Ainda

    não. Mas comece a escrever seus apps e estudar @_rafaeltoledo