SlideShare uma empresa Scribd logo
Desenvolvimento moderno
de aplicativos Android
Um guia [quase] completo
+Nelson Glauber
@nglauber

www.nglauber.com.br

youtube.com/nglauber
TDCSP2018

#TheDevConf
Estou começando a trabalhar com Android.

O que eu devo estudar/aprender? 🤔
Curso de Android (2009)
Introdução ao Android................. 1h
Configuração do Ambiente.............. 1h
Conceitos Básicos..................... 2h
Activity.............................. 4h
Intents............................... 2h
Interface Gráfica (Layouts e Views)... 8h
IntentFilter.......................... 2h
BroadcastReceiver..................... 1h
Notification.......................... 1h
Service............................... 2h
AlarmManager.......................... 1h
Handler............................... 1h
SQLite................................ 4h
ContentProvider....................... 2h
Mapas e GPS........................... 3h
HTTP, Sockets e Web Services.......... 4h
SMS................................... 1h
Audio e Vídeo......................... 2h
-----------------------------------------
TOTAL 42h
O que é ser um
desenvolvedor Android
“moderno"?
ATUAL
Comunidade
1
slack.androiddevbr.org
Google Developers 

Groups
Comunidade é troca de
conhecimento.

Aprenda com ela

e RETRIBUA!
github.com/nglauber/tdcapp
Linguagem
2
Outras linguagens evoluíram… 

o Java (para Android) nem tanto
Porque Kotlin?
• Linguagem moderna, concisa, intuitiva e fácil de
aprender.
• Open Source, mantido pela JetBrains.
• Suporte nativo no Android Studio.
• 100% Inter-operável com Java. Você pode possuir
código Java e Kotlin no mesmo projeto (inclusive libs).
• Menos verboso. Você escreve menos código.
• …
type inference • null safety • immutability • string templates
• control structures if/when/try return values • for in range
• default params in methods • destructuring • data classes
• properties • sealed classes • default implementation for
interfaces • smart cast • delegates (lazy, observable,
vetoable, map) • extension functions/properties • std lib
functions (apply, let, also, with, run) • synthetic imports •
lambdas • high-order-functions • type alias • operator
overloading • collections functions • object=singleton •
named imports • inner functions • coroutines • parcelize • …
youtu.be/FHZ6bI3zb4M
Saiba mais…
• Site Oficial (kotlinlang.org)
• Editor on-line (try.kotlinlang.org)
• Kotlin Koans (try.kotlinlang.org/koans)
• Antonio Leiva’s book (antonioleiva.com/google-kotlin)
• Como eu aprendi Kotlin (bit.do/nglauber_kotlin)
• Kotlin Guides (android.github.io/kotlin-guides)
3 Criação de
Layouts
Layouts
• FrameLayout
• RelativeLayout
• LinearLayout
• TableLayout
• GridLayout
• entre outros…
ConstraintLayout
• Implementa o conceito de flat layout. Melhorando a
performance.
• É um mix dos demais layouts, com mais recursos.
• É muito mais fácil criar os layout utilizando visual
editor. Mas o XML continua legível.
• É uma biblioteca separada do S.O., o que facilita a
atualização.
" 11 componentes a mais!!!
youtu.be/YSz-k4sbUiE
Saiba mais…
• What’s new in Constraint Layout Design Tools

http://youtu.be/ytZteMo4ETk
• Introduction to Motion Layout

https://medium.com/google-developers/introduction-to-
motionlayout-part-i-29208674b10d
4 Acesso à web
github.com/google/gson
square.github.io/okhttp
square.github.io/retrofit
5 Programação
Assíncrona
60 FPS
1000ms / 60 frames
= 

16.666ms per frame
Assíncrono
• Threads and Handlers
• AsyncTask
• Loaders
RX Java
É uma biblioteca que permite representar qualquer
operação como um fluxo assíncrono de dados criado
por qualquer thread, de forma declarativa e
consumida por múltiplos objetos em várias threads.
override fun getSessionsByModality(eventId: Long,
modalityId: Long): Observable<List<Session>> {
return Observable.zip(
remoteDataSource.getSessionsByModality(eventId, modalityId),
localDataSource.getBookmarkedSessions(eventId, modalityId),
BiFunction { remoteList, localList ->
remoteList.map { remoteSession ->
if (localList.find { it.id == remoteSession.id } != null) {
remoteSession.copy(bookmarked = true)
} else {
remoteSession
}
}
}
)
}
RxJava + Retrofit = ❤
interface TdcWebService {
@GET(PATH_GET_EVENTS)
fun getEvents(): Observable<List<TdcEvent>>
@GET(PATH_GET_MODALITIES_BY_EVENT)
fun getModalitiesByEvent(
@Path(PARAM_EVENT_ID) eventId: Int): Observable<List<TdcModality>>
@GET(PATH_GET_SESSIONS_BY_MODALITY)
fun getSessionsByModality(
@Path(PARAM_EVENT_ID) eventId: Int,
@Path(PARAM_MODALITY_ID) modalityId: Int): Observable<List<TdcSession>>
@GET(PATH_GET_SPEAKERS_BY_SESSION)
fun getSpeakersBySession(
@Path(PARAM_EVENT_ID) eventId: Int,
@Path(PARAM_MODALITY_ID) modalityId: Int,
@Path(PARAM_SESSION_ID) sessionId: Int): Observable<List<TdcSpeaker>>
}
val service = Retrofit.Builder()
.baseUrl(TdcWebService.API_BASE_URL)
.client(okHttpClient)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(TdcWebService::class.java)
service.getEvents()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { eventsList ->
// do something
}
youtu.be/ZxhX7a-ScUs
bit.ly/nglauber_rxjava
Coroutines
suspend fun method1(): String {
delay(5, TimeUnit.SECONDS)
Log.d("NGVL", "async1 -> ${Thread.currentThread().name}")
return "Async1"
}
suspend fun method2(): String {
delay(2, TimeUnit.SECONDS)
Log.d("NGVL", "async2 -> ${Thread.currentThread().name}")
return "Async2"
}
fun load() {
launch(UI) {
val s = try {
val a = async { method1() }
val b = async { method2() }
"${a.await()} ${b.await()}"
} catch (e: Exception) {
"Error!"
}
button.text = s
}
}
youtu.be/Xo5Fp4UqXY8
Saiba mais…
• KotlinConf 2017 - Introduction to Coroutines by Roman
Elizarov

https://youtu.be/_hfBv0a09Jc

• KotlinConf 2017 - Deep Dive into Coroutines on JVM by
Roman Elizarov

https://youtu.be/YrrUCSi72E8
6
Organize sua
camada de
apresentação
Pague as consequências!!!
• Código altamente acoplado
• Difícil de manter e adicionar
novas funcionalidades
• Difícil de testar,
consequentemente instável
MVP
View
IView
Presenter Model
Interação 

do usuário
Request
DadosLógica de UI
implements
MVVM
View ViewModel Model
Observes
Interação 

do usuário
Dados
Request
7 Android Architecture
Components
ViewModel
class ScoreViewModel: ViewModel() {
var score = Score()
fun updateTeamA() {
score.teamA++
}
fun updateTeamB() {
score.teamB++
}
fun reset(){
score.teamA = 0
score.teamB = 0
}
}
class MainActivity : AppCompatActivity() {
private val viewModel: ScoreViewModel by lazy {
ViewModelProviders.of(this).get(ScoreViewModel::class.java)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val score = viewModel.score
...
}
}
LiveData
• LiveData armazena dados observáveis (Observable) e
notifica os observadores (Observers) quando esses dados
mudam para que a UI seja atualizada.
• O LiveData é lifecycle-aware. Ele só notificará a UI se a
Activity/Fragment estiver no estado STARTED ou
RESUMED.
class SessionsListViewModel : ViewModel() {
val sessions = MutableLiveData<List<Session>>()
fun loadSessions() {
// Carregar dados da web...
sessions.value = listFromWeb
}
...
}
class SessionsListActivity : AppCompatActivity() {
private val viewModel: SessionsListViewModel /*init*/
private val adapter: SessionsAdapter /*init*/
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sessions_list)
viewModel.sessions.observe(this, Observer { sessions ->
adapter.setItems(sessions)
})
viewModel.loadSessions()
...
}
}
Lifecycle
• Lifecycle é um objeto que define um ciclo de vida
• LifecycleOwner é uma interface para objetos com um
ciclo de vida
• A partir da appcompat 26.1, Activity e Fragment
implementam LifecycleOwner.
• LifecycleObserver é uma interface para observar um
LifecycleOwner
class SessionsListViewModel: ViewModel(), LifecycleObserver {
val sessions: MutableLiveData<List<Session>> = MutableLiveData()
fun fetchSessions() {
// load from web
state.value = listFromWeb
}
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun fetchIfNeeded() {
if (state.value == null) {
fetchSessions()
}
}
}
class SessionsListActivity : AppCompatActivity() {
private val viewModel: SessionsListViewModel /* init */
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
lifecycle.addObserver(viewModel)
}
}
Data Binding
• Facilita a ligação entre View Model e View
• Estende os arquivos de layout com micro-expressões
• Muito útil em telas de input de dados
https://github.com/nglauber/playground/tree/master/android/LivrosFirebase
val book = intent.getSerializableExtra(EXTRA_BOOK) as Book
Glide.with(this).load(book.coverUrl).into(imgCover)
txtTitle.text = book.title
txtAuthor.text = book.author
txtPages.text = getString(R.string.text_format_book_pages, book.pages)
txtYear.text = getString(R.string.text_format_book_year, book.year)
txtPublisher.text = book.publisher.name
txtAvailable.text =
if (book.isAvailable())
R.string.text_book_available
else
R.string.text_book_unavailable
txtMediaType.text = book.mediaType.toString()
ratingBook.numStars = book.rating
book.coverUrl = imageFile.absolutePath
book.title = editPages.text.toString()
book.author = editAuthor.text.toString()
book.pages = editPages.text.toString().toInt()
book.year = editYear.text.toString().toInt()
book.publisher = spinnerPublisher.selectedItem as Publisher
book.available = checkAvailable.isChecked
book.mediaTypeValue =
if (radioMediaEbook.isChecked) MediaType.EBOOK
else MediaType.PAPER
book.rating = ratingBook.rating
saveBook(book)
val binding: ActivityEditBinding by lazy {
DataBindingUtil.setContentView<ActivityEditBinding>(
this, R.layout.activity_edit
)
}
...
binding.book = intent.getSerializableExtra(EXTRA_BOOK) as Book
...
saveBook(binding.book)
<layout ...>
<data>
...
<import type="br.com.nglauber.livrosfirebase.model.MediaType" />
<variable name="book"
type="br.com.nglauber.livrosfirebase.model.Book" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout ...>
<ImageView android:src="@{book.coverUrl}" ... />
<EditText android:text="@={book.title}" ... />
<EditText android:text="@={book.author}" ... />
<EditText android:text="@={book.pages}" ... />
<EditText android:text="@={book.year}" ... />
<Spinner ...>
<CheckBox android:checked="@={book.available}" ... />
<RadioGroup ...>
<RadioButton ...
android:checked="@{book.mediaTypeValue == MediaType.EBOOK}" ... />
<RadioButton ...
android:checked="@{book.mediaTypeValue == MediaType.PAPER}" ... />
</RadioGroup>
<RatingBar
android:rating="@={book.rating}" ... />
...
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
youtu.be/0UXeUhU8AiE?t=27m19s
Room
• ORM para Android sobre o SQLite.
• Suporta atualização automática da UI com LiveData ou
RXJava
Room
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
data class Session(
@PrimaryKey(autoGenerate = false)
val id: Long,
val slot: Int,
val order: Int,
val activated: Boolean,
val title: String,
val description: String,
val type: Int,
val time: String,
val eventId: Long,
val modalityId: Long
)
import androidx.room.*
import io.reactivex.Flowable
@Dao
interface SessionDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(session: Session): Long
@Delete
fun delete(session: Session): Int
@Update
fun update(session: Session): Int
@Query("SELECT * FROM Session WHERE eventId = :eventId AND modalityId = :modalityId")
fun sessionsByModality(eventId: Long, modalityId: Long): Flowable<List<Session>>
}
@Database(
entities = [
Session::class,
Speaker::class,
SessionSpeakerJoin::class
],
version = 1
)
abstract class TdcDatabase : RoomDatabase() {
abstract fun sessionDao(): SessionDao
abstract fun speakerDao(): SpeakerDao
abstract fun sessionSpeakerJoinDao(): SessionSpeakerJoinDao
}
var db = Room.databaseBuilder(
context,
TdcDatabase::class.java)
.build()
var sessionDao = db.sessionDao()
val session = Session(/* init */)
val id = sessionDao.insert(session)
sessionDao.sessionsByModality(eventId, modalityId)

.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { sessions ->
// iterate over the sessions
}
youtu.be/MduVIAlqk8I
Arquitetura
8 Arquitetura Limpa
https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html
UI (app)
Presentation
Domain
Remote Local
Repository
https://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/
github.com/googlesamples/android-architecture
9 Injeção de
Dependências
google.github.io/dagger
insert-koin.io
kodein.org/Kodein-DI
10 Testes
Testes
UI Automator
robolectric.org
site.mockito.org
11 Firebase
https://goo.gl/A6GW4s
• Você não precisa usar todos esses
recursos no mesmo app…
• Na verdade, você não precisa usar
nenhum!
• Mais importante do que saber quando
USAR é saber quando NÃO USAR 😉
• Mas é essencial conhecer tópicos,
saber seus prós e contras e utilizá-los
adequadamente 💡
Um desenvolvedor
moderno…
2 Kotlin
3 Constraint Layout
4 Retrofit + OkHttp + GSON
5 RxJava e Coroutines
6 MVP ou MVVM
7 Architecture Components
8 Clean Architecture
9 Injeção de dependências
10 Testes
11 Firebase
1 Comunidade
@nglauber
+NelsonGlauber
www.nglauber.com.br

Obrigado!
youtube.com/nglauber
Dúvidas?

Mais conteúdo relacionado

Mais procurados

Introdução à MEAN Stack
Introdução à MEAN StackIntrodução à MEAN Stack
Introdução à MEAN Stack
Bruno Catão
 
Criando uma arquitetura de front-end do zero
Criando uma arquitetura de front-end do zeroCriando uma arquitetura de front-end do zero
Criando uma arquitetura de front-end do zero
Eduardo Shiota Yasuda
 
Apple Watch - Digital Day da CI&T
Apple Watch - Digital Day da CI&TApple Watch - Digital Day da CI&T
Apple Watch - Digital Day da CI&T
Juliana Chahoud
 
Swift, a nova linguagem de programação da Apple (CocoaHeads Sao Paulo)
Swift, a nova linguagem de programação da Apple (CocoaHeads Sao Paulo)Swift, a nova linguagem de programação da Apple (CocoaHeads Sao Paulo)
Swift, a nova linguagem de programação da Apple (CocoaHeads Sao Paulo)
Juliana Chahoud
 
React js
React js React js
React js
Alexandre Rosa
 
Python 06
Python 06Python 06
Python 06
Bruno Catão
 
JavaScript e JQuery para Webdesigners
JavaScript e JQuery para WebdesignersJavaScript e JQuery para Webdesigners
JavaScript e JQuery para Webdesigners
Harlley Oliveira
 
Desafios do Desenvolvimento de Front-end em um e-commerce
Desafios do Desenvolvimento de Front-end em um e-commerceDesafios do Desenvolvimento de Front-end em um e-commerce
Desafios do Desenvolvimento de Front-end em um e-commerce
Eduardo Shiota Yasuda
 
jQuery básico (parte 3)
jQuery básico (parte 3)jQuery básico (parte 3)
jQuery básico (parte 3)
Luís Cobucci
 
Integrações de APIs do Google no iOS (DevFest NE e SP)
Integrações de APIs do Google no iOS (DevFest NE e SP)Integrações de APIs do Google no iOS (DevFest NE e SP)
Integrações de APIs do Google no iOS (DevFest NE e SP)
Juliana Chahoud
 
Semcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com Swift
Semcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com SwiftSemcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com Swift
Semcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com Swift
Juliana Chahoud
 
Desenvolvendo para iOS com Cocoa-Touch
Desenvolvendo para iOS com Cocoa-TouchDesenvolvendo para iOS com Cocoa-Touch
Desenvolvendo para iOS com Cocoa-Touch
Campus Party Brasil
 
Java script aula 10 - angularjs
Java script   aula 10 - angularjsJava script   aula 10 - angularjs
Java script aula 10 - angularjs
Cristiano Pires Martins
 
Desenvolvimento iOS
Desenvolvimento iOSDesenvolvimento iOS
Desenvolvimento iOS
André Espeiorin
 
Java script - funções
Java script - funçõesJava script - funções
Java script - funções
Cristiano Pires Martins
 
RubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoRubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direito
Cezinha Anjos
 
O que aprendi após 3 bilhões de jobs processados no Sidekiq
O que aprendi após 3 bilhões de jobs processados no SidekiqO que aprendi após 3 bilhões de jobs processados no Sidekiq
O que aprendi após 3 bilhões de jobs processados no Sidekiq
Anderson Dias
 
ODIG - Javascript, DOM Elements e jQuery
ODIG - Javascript, DOM Elements e jQueryODIG - Javascript, DOM Elements e jQuery
ODIG - Javascript, DOM Elements e jQuery
Marketing Digital ODIG
 
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
lucashungaro
 
Java script aula 02 - operadores
Java script   aula 02 - operadoresJava script   aula 02 - operadores
Java script aula 02 - operadores
Cristiano Pires Martins
 

Mais procurados (20)

Introdução à MEAN Stack
Introdução à MEAN StackIntrodução à MEAN Stack
Introdução à MEAN Stack
 
Criando uma arquitetura de front-end do zero
Criando uma arquitetura de front-end do zeroCriando uma arquitetura de front-end do zero
Criando uma arquitetura de front-end do zero
 
Apple Watch - Digital Day da CI&T
Apple Watch - Digital Day da CI&TApple Watch - Digital Day da CI&T
Apple Watch - Digital Day da CI&T
 
Swift, a nova linguagem de programação da Apple (CocoaHeads Sao Paulo)
Swift, a nova linguagem de programação da Apple (CocoaHeads Sao Paulo)Swift, a nova linguagem de programação da Apple (CocoaHeads Sao Paulo)
Swift, a nova linguagem de programação da Apple (CocoaHeads Sao Paulo)
 
React js
React js React js
React js
 
Python 06
Python 06Python 06
Python 06
 
JavaScript e JQuery para Webdesigners
JavaScript e JQuery para WebdesignersJavaScript e JQuery para Webdesigners
JavaScript e JQuery para Webdesigners
 
Desafios do Desenvolvimento de Front-end em um e-commerce
Desafios do Desenvolvimento de Front-end em um e-commerceDesafios do Desenvolvimento de Front-end em um e-commerce
Desafios do Desenvolvimento de Front-end em um e-commerce
 
jQuery básico (parte 3)
jQuery básico (parte 3)jQuery básico (parte 3)
jQuery básico (parte 3)
 
Integrações de APIs do Google no iOS (DevFest NE e SP)
Integrações de APIs do Google no iOS (DevFest NE e SP)Integrações de APIs do Google no iOS (DevFest NE e SP)
Integrações de APIs do Google no iOS (DevFest NE e SP)
 
Semcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com Swift
Semcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com SwiftSemcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com Swift
Semcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com Swift
 
Desenvolvendo para iOS com Cocoa-Touch
Desenvolvendo para iOS com Cocoa-TouchDesenvolvendo para iOS com Cocoa-Touch
Desenvolvendo para iOS com Cocoa-Touch
 
Java script aula 10 - angularjs
Java script   aula 10 - angularjsJava script   aula 10 - angularjs
Java script aula 10 - angularjs
 
Desenvolvimento iOS
Desenvolvimento iOSDesenvolvimento iOS
Desenvolvimento iOS
 
Java script - funções
Java script - funçõesJava script - funções
Java script - funções
 
RubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoRubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direito
 
O que aprendi após 3 bilhões de jobs processados no Sidekiq
O que aprendi após 3 bilhões de jobs processados no SidekiqO que aprendi após 3 bilhões de jobs processados no Sidekiq
O que aprendi após 3 bilhões de jobs processados no Sidekiq
 
ODIG - Javascript, DOM Elements e jQuery
ODIG - Javascript, DOM Elements e jQueryODIG - Javascript, DOM Elements e jQuery
ODIG - Javascript, DOM Elements e jQuery
 
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
Coisas que aprendi e quero passar adiante - RubyConf Brasil 2010
 
Java script aula 02 - operadores
Java script   aula 02 - operadoresJava script   aula 02 - operadores
Java script aula 02 - operadores
 

Semelhante a Desenvolvimento Moderno de Aplicativos Android

Desenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos AndroidDesenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos Android
Nelson Glauber Leal
 
JSF 2.0 e ScrumToys
JSF 2.0 e ScrumToysJSF 2.0 e ScrumToys
JSF 2.0 e ScrumToys
Dr. Spock
 
Java Seminar
Java SeminarJava Seminar
Java Seminar
armeniocardoso
 
JSF 2.0: Uma Evolução nas Interfaces Web com Java
JSF 2.0: Uma Evolução nas Interfaces Web com JavaJSF 2.0: Uma Evolução nas Interfaces Web com Java
JSF 2.0: Uma Evolução nas Interfaces Web com Java
Dr. Spock
 
Desenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App EngineDesenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App Engine
Campus Party Brasil
 
JSF 2.0 e ScrumToys
JSF 2.0 e ScrumToysJSF 2.0 e ScrumToys
JSF 2.0 e ScrumToys
Dr. Spock
 
Django Apps - Do Núcleo a Otimização
Django Apps - Do Núcleo a OtimizaçãoDjango Apps - Do Núcleo a Otimização
Django Apps - Do Núcleo a Otimização
Leandro Zanuz
 
Introdução Play framework
Introdução Play frameworkIntrodução Play framework
Introdução Play framework
Keuller Magalhães
 
Drupal 8: desenvolvendo fora da ilha
Drupal 8: desenvolvendo fora da ilhaDrupal 8: desenvolvendo fora da ilha
Drupal 8: desenvolvendo fora da ilha
Luiz Filho
 
Apresentacão Android Components - Programando em camadas
Apresentacão Android Components - Programando em camadasApresentacão Android Components - Programando em camadas
Apresentacão Android Components - Programando em camadas
Victor Aldir
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1
Sliedesharessbarbosa
 
Kotlin first
Kotlin firstKotlin first
Kotlin first
Suelen Silva
 
JavaFX 2 - TDC 2012
JavaFX 2 - TDC 2012JavaFX 2 - TDC 2012
JavaFX 2 - TDC 2012
jesuinoPower
 
android
androidandroid
Java web fj21-- apostila da caelum
Java web fj21-- apostila da caelumJava web fj21-- apostila da caelum
Java web fj21-- apostila da caelum
Agenor Neto
 
Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007
Rafael Benevides
 
Android Aula 5
Android Aula 5Android Aula 5
Android Aula 5
Erisvaldo Junior
 
Computação Móvel 2012.2 - Android
Computação Móvel 2012.2 - AndroidComputação Móvel 2012.2 - Android
Computação Móvel 2012.2 - Android
Tiago Bencardino
 
Minicurso Android Ronildo Oliveira
Minicurso Android  Ronildo OliveiraMinicurso Android  Ronildo Oliveira
Minicurso Android Ronildo Oliveira
Ronildo Oliveira
 
JavaFX 2
JavaFX 2JavaFX 2
JavaFX 2
jesuinoPower
 

Semelhante a Desenvolvimento Moderno de Aplicativos Android (20)

Desenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos AndroidDesenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos Android
 
JSF 2.0 e ScrumToys
JSF 2.0 e ScrumToysJSF 2.0 e ScrumToys
JSF 2.0 e ScrumToys
 
Java Seminar
Java SeminarJava Seminar
Java Seminar
 
JSF 2.0: Uma Evolução nas Interfaces Web com Java
JSF 2.0: Uma Evolução nas Interfaces Web com JavaJSF 2.0: Uma Evolução nas Interfaces Web com Java
JSF 2.0: Uma Evolução nas Interfaces Web com Java
 
Desenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App EngineDesenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App Engine
 
JSF 2.0 e ScrumToys
JSF 2.0 e ScrumToysJSF 2.0 e ScrumToys
JSF 2.0 e ScrumToys
 
Django Apps - Do Núcleo a Otimização
Django Apps - Do Núcleo a OtimizaçãoDjango Apps - Do Núcleo a Otimização
Django Apps - Do Núcleo a Otimização
 
Introdução Play framework
Introdução Play frameworkIntrodução Play framework
Introdução Play framework
 
Drupal 8: desenvolvendo fora da ilha
Drupal 8: desenvolvendo fora da ilhaDrupal 8: desenvolvendo fora da ilha
Drupal 8: desenvolvendo fora da ilha
 
Apresentacão Android Components - Programando em camadas
Apresentacão Android Components - Programando em camadasApresentacão Android Components - Programando em camadas
Apresentacão Android Components - Programando em camadas
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1
 
Kotlin first
Kotlin firstKotlin first
Kotlin first
 
JavaFX 2 - TDC 2012
JavaFX 2 - TDC 2012JavaFX 2 - TDC 2012
JavaFX 2 - TDC 2012
 
android
androidandroid
android
 
Java web fj21-- apostila da caelum
Java web fj21-- apostila da caelumJava web fj21-- apostila da caelum
Java web fj21-- apostila da caelum
 
Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007
 
Android Aula 5
Android Aula 5Android Aula 5
Android Aula 5
 
Computação Móvel 2012.2 - Android
Computação Móvel 2012.2 - AndroidComputação Móvel 2012.2 - Android
Computação Móvel 2012.2 - Android
 
Minicurso Android Ronildo Oliveira
Minicurso Android  Ronildo OliveiraMinicurso Android  Ronildo Oliveira
Minicurso Android Ronildo Oliveira
 
JavaFX 2
JavaFX 2JavaFX 2
JavaFX 2
 

Mais de Nelson Glauber Leal

Seu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose MultiplatformSeu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose Multiplatform
Nelson Glauber Leal
 
Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023
Nelson Glauber Leal
 
Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023
Nelson Glauber Leal
 
Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)
Nelson Glauber Leal
 
Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021
Nelson Glauber Leal
 
Jetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on AndroidJetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on Android
Nelson Glauber Leal
 
Jetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no AndroidJetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no Android
Nelson Glauber Leal
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
Nelson Glauber Leal
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
Nelson Glauber Leal
 
O que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor AndroidO que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor Android
Nelson Glauber Leal
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
Nelson Glauber Leal
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
Nelson Glauber Leal
 
Aplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackAplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e Jetpack
Nelson Glauber Leal
 
Mastering Kotlin Standard Library
Mastering Kotlin Standard LibraryMastering Kotlin Standard Library
Mastering Kotlin Standard Library
Nelson Glauber Leal
 
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackAplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & Jetpack
Nelson Glauber Leal
 
Introdução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinIntrodução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com Kotlin
Nelson Glauber Leal
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using Room
Nelson Glauber Leal
 
Arquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com JetpackArquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com Jetpack
Nelson Glauber Leal
 
Turbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com KotlinTurbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com Kotlin
Nelson Glauber Leal
 
Tudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint LayoutTudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint Layout
Nelson Glauber Leal
 

Mais de Nelson Glauber Leal (20)

Seu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose MultiplatformSeu primeiro app Android e iOS com Compose Multiplatform
Seu primeiro app Android e iOS com Compose Multiplatform
 
Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023
 
Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023
 
Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)
 
Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021
 
Jetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on AndroidJetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on Android
 
Jetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no AndroidJetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no Android
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
 
O que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor AndroidO que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor Android
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
 
Aplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackAplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e Jetpack
 
Mastering Kotlin Standard Library
Mastering Kotlin Standard LibraryMastering Kotlin Standard Library
Mastering Kotlin Standard Library
 
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackAplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & Jetpack
 
Introdução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinIntrodução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com Kotlin
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using Room
 
Arquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com JetpackArquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com Jetpack
 
Turbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com KotlinTurbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com Kotlin
 
Tudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint LayoutTudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint Layout
 

Desenvolvimento Moderno de Aplicativos Android

  • 1. Desenvolvimento moderno de aplicativos Android Um guia [quase] completo +Nelson Glauber @nglauber
 www.nglauber.com.br
 youtube.com/nglauber TDCSP2018
 #TheDevConf
  • 2. Estou começando a trabalhar com Android.
 O que eu devo estudar/aprender? 🤔
  • 3. Curso de Android (2009) Introdução ao Android................. 1h Configuração do Ambiente.............. 1h Conceitos Básicos..................... 2h Activity.............................. 4h Intents............................... 2h Interface Gráfica (Layouts e Views)... 8h IntentFilter.......................... 2h BroadcastReceiver..................... 1h Notification.......................... 1h Service............................... 2h AlarmManager.......................... 1h Handler............................... 1h SQLite................................ 4h ContentProvider....................... 2h Mapas e GPS........................... 3h HTTP, Sockets e Web Services.......... 4h SMS................................... 1h Audio e Vídeo......................... 2h ----------------------------------------- TOTAL 42h
  • 4. O que é ser um desenvolvedor Android “moderno"? ATUAL
  • 7. Comunidade é troca de conhecimento.
 Aprenda com ela
 e RETRIBUA!
  • 10. Outras linguagens evoluíram… 
 o Java (para Android) nem tanto
  • 11.
  • 12. Porque Kotlin? • Linguagem moderna, concisa, intuitiva e fácil de aprender. • Open Source, mantido pela JetBrains. • Suporte nativo no Android Studio. • 100% Inter-operável com Java. Você pode possuir código Java e Kotlin no mesmo projeto (inclusive libs). • Menos verboso. Você escreve menos código. • …
  • 13. type inference • null safety • immutability • string templates • control structures if/when/try return values • for in range • default params in methods • destructuring • data classes • properties • sealed classes • default implementation for interfaces • smart cast • delegates (lazy, observable, vetoable, map) • extension functions/properties • std lib functions (apply, let, also, with, run) • synthetic imports • lambdas • high-order-functions • type alias • operator overloading • collections functions • object=singleton • named imports • inner functions • coroutines • parcelize • …
  • 15. Saiba mais… • Site Oficial (kotlinlang.org) • Editor on-line (try.kotlinlang.org) • Kotlin Koans (try.kotlinlang.org/koans) • Antonio Leiva’s book (antonioleiva.com/google-kotlin) • Como eu aprendi Kotlin (bit.do/nglauber_kotlin) • Kotlin Guides (android.github.io/kotlin-guides)
  • 17. Layouts • FrameLayout • RelativeLayout • LinearLayout • TableLayout • GridLayout • entre outros…
  • 18. ConstraintLayout • Implementa o conceito de flat layout. Melhorando a performance. • É um mix dos demais layouts, com mais recursos. • É muito mais fácil criar os layout utilizando visual editor. Mas o XML continua legível. • É uma biblioteca separada do S.O., o que facilita a atualização.
  • 19.
  • 20. " 11 componentes a mais!!!
  • 22.
  • 23. Saiba mais… • What’s new in Constraint Layout Design Tools
 http://youtu.be/ytZteMo4ETk • Introduction to Motion Layout
 https://medium.com/google-developers/introduction-to- motionlayout-part-i-29208674b10d
  • 24. 4 Acesso à web
  • 27. 60 FPS 1000ms / 60 frames = 
 16.666ms per frame
  • 28. Assíncrono • Threads and Handlers • AsyncTask • Loaders
  • 29. RX Java É uma biblioteca que permite representar qualquer operação como um fluxo assíncrono de dados criado por qualquer thread, de forma declarativa e consumida por múltiplos objetos em várias threads.
  • 30. override fun getSessionsByModality(eventId: Long, modalityId: Long): Observable<List<Session>> { return Observable.zip( remoteDataSource.getSessionsByModality(eventId, modalityId), localDataSource.getBookmarkedSessions(eventId, modalityId), BiFunction { remoteList, localList -> remoteList.map { remoteSession -> if (localList.find { it.id == remoteSession.id } != null) { remoteSession.copy(bookmarked = true) } else { remoteSession } } } ) }
  • 32. interface TdcWebService { @GET(PATH_GET_EVENTS) fun getEvents(): Observable<List<TdcEvent>> @GET(PATH_GET_MODALITIES_BY_EVENT) fun getModalitiesByEvent( @Path(PARAM_EVENT_ID) eventId: Int): Observable<List<TdcModality>> @GET(PATH_GET_SESSIONS_BY_MODALITY) fun getSessionsByModality( @Path(PARAM_EVENT_ID) eventId: Int, @Path(PARAM_MODALITY_ID) modalityId: Int): Observable<List<TdcSession>> @GET(PATH_GET_SPEAKERS_BY_SESSION) fun getSpeakersBySession( @Path(PARAM_EVENT_ID) eventId: Int, @Path(PARAM_MODALITY_ID) modalityId: Int, @Path(PARAM_SESSION_ID) sessionId: Int): Observable<List<TdcSpeaker>> }
  • 33. val service = Retrofit.Builder() .baseUrl(TdcWebService.API_BASE_URL) .client(okHttpClient) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build() .create(TdcWebService::class.java) service.getEvents() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe { eventsList -> // do something }
  • 36. suspend fun method1(): String { delay(5, TimeUnit.SECONDS) Log.d("NGVL", "async1 -> ${Thread.currentThread().name}") return "Async1" } suspend fun method2(): String { delay(2, TimeUnit.SECONDS) Log.d("NGVL", "async2 -> ${Thread.currentThread().name}") return "Async2" } fun load() { launch(UI) { val s = try { val a = async { method1() } val b = async { method2() } "${a.await()} ${b.await()}" } catch (e: Exception) { "Error!" } button.text = s } }
  • 38. Saiba mais… • KotlinConf 2017 - Introduction to Coroutines by Roman Elizarov
 https://youtu.be/_hfBv0a09Jc
 • KotlinConf 2017 - Deep Dive into Coroutines on JVM by Roman Elizarov
 https://youtu.be/YrrUCSi72E8
  • 40.
  • 41. Pague as consequências!!! • Código altamente acoplado • Difícil de manter e adicionar novas funcionalidades • Difícil de testar, consequentemente instável
  • 42. MVP View IView Presenter Model Interação 
 do usuário Request DadosLógica de UI implements
  • 43.
  • 44. MVVM View ViewModel Model Observes Interação 
 do usuário Dados Request
  • 45.
  • 47.
  • 48.
  • 50. class ScoreViewModel: ViewModel() { var score = Score() fun updateTeamA() { score.teamA++ } fun updateTeamB() { score.teamB++ } fun reset(){ score.teamA = 0 score.teamB = 0 } }
  • 51. class MainActivity : AppCompatActivity() { private val viewModel: ScoreViewModel by lazy { ViewModelProviders.of(this).get(ScoreViewModel::class.java) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val score = viewModel.score ... } }
  • 52. LiveData • LiveData armazena dados observáveis (Observable) e notifica os observadores (Observers) quando esses dados mudam para que a UI seja atualizada. • O LiveData é lifecycle-aware. Ele só notificará a UI se a Activity/Fragment estiver no estado STARTED ou RESUMED.
  • 53. class SessionsListViewModel : ViewModel() { val sessions = MutableLiveData<List<Session>>() fun loadSessions() { // Carregar dados da web... sessions.value = listFromWeb } ... }
  • 54. class SessionsListActivity : AppCompatActivity() { private val viewModel: SessionsListViewModel /*init*/ private val adapter: SessionsAdapter /*init*/ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_sessions_list) viewModel.sessions.observe(this, Observer { sessions -> adapter.setItems(sessions) }) viewModel.loadSessions() ... } }
  • 55. Lifecycle • Lifecycle é um objeto que define um ciclo de vida • LifecycleOwner é uma interface para objetos com um ciclo de vida • A partir da appcompat 26.1, Activity e Fragment implementam LifecycleOwner. • LifecycleObserver é uma interface para observar um LifecycleOwner
  • 56. class SessionsListViewModel: ViewModel(), LifecycleObserver { val sessions: MutableLiveData<List<Session>> = MutableLiveData() fun fetchSessions() { // load from web state.value = listFromWeb } @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun fetchIfNeeded() { if (state.value == null) { fetchSessions() } } }
  • 57. class SessionsListActivity : AppCompatActivity() { private val viewModel: SessionsListViewModel /* init */ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ... lifecycle.addObserver(viewModel) } }
  • 58. Data Binding • Facilita a ligação entre View Model e View • Estende os arquivos de layout com micro-expressões • Muito útil em telas de input de dados
  • 60. val book = intent.getSerializableExtra(EXTRA_BOOK) as Book Glide.with(this).load(book.coverUrl).into(imgCover) txtTitle.text = book.title txtAuthor.text = book.author txtPages.text = getString(R.string.text_format_book_pages, book.pages) txtYear.text = getString(R.string.text_format_book_year, book.year) txtPublisher.text = book.publisher.name txtAvailable.text = if (book.isAvailable()) R.string.text_book_available else R.string.text_book_unavailable txtMediaType.text = book.mediaType.toString() ratingBook.numStars = book.rating
  • 61. book.coverUrl = imageFile.absolutePath book.title = editPages.text.toString() book.author = editAuthor.text.toString() book.pages = editPages.text.toString().toInt() book.year = editYear.text.toString().toInt() book.publisher = spinnerPublisher.selectedItem as Publisher book.available = checkAvailable.isChecked book.mediaTypeValue = if (radioMediaEbook.isChecked) MediaType.EBOOK else MediaType.PAPER book.rating = ratingBook.rating saveBook(book)
  • 62. val binding: ActivityEditBinding by lazy { DataBindingUtil.setContentView<ActivityEditBinding>( this, R.layout.activity_edit ) } ... binding.book = intent.getSerializableExtra(EXTRA_BOOK) as Book ... saveBook(binding.book)
  • 63. <layout ...> <data> ... <import type="br.com.nglauber.livrosfirebase.model.MediaType" /> <variable name="book" type="br.com.nglauber.livrosfirebase.model.Book" /> </data> <androidx.constraintlayout.widget.ConstraintLayout ...> <ImageView android:src="@{book.coverUrl}" ... /> <EditText android:text="@={book.title}" ... /> <EditText android:text="@={book.author}" ... /> <EditText android:text="@={book.pages}" ... /> <EditText android:text="@={book.year}" ... /> <Spinner ...> <CheckBox android:checked="@={book.available}" ... /> <RadioGroup ...> <RadioButton ... android:checked="@{book.mediaTypeValue == MediaType.EBOOK}" ... /> <RadioButton ... android:checked="@{book.mediaTypeValue == MediaType.PAPER}" ... /> </RadioGroup> <RatingBar android:rating="@={book.rating}" ... /> ... </androidx.constraintlayout.widget.ConstraintLayout> </layout>
  • 65. Room • ORM para Android sobre o SQLite. • Suporta atualização automática da UI com LiveData ou RXJava
  • 66. Room
  • 67. import androidx.room.Entity import androidx.room.PrimaryKey @Entity data class Session( @PrimaryKey(autoGenerate = false) val id: Long, val slot: Int, val order: Int, val activated: Boolean, val title: String, val description: String, val type: Int, val time: String, val eventId: Long, val modalityId: Long )
  • 68. import androidx.room.* import io.reactivex.Flowable @Dao interface SessionDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(session: Session): Long @Delete fun delete(session: Session): Int @Update fun update(session: Session): Int @Query("SELECT * FROM Session WHERE eventId = :eventId AND modalityId = :modalityId") fun sessionsByModality(eventId: Long, modalityId: Long): Flowable<List<Session>> }
  • 69. @Database( entities = [ Session::class, Speaker::class, SessionSpeakerJoin::class ], version = 1 ) abstract class TdcDatabase : RoomDatabase() { abstract fun sessionDao(): SessionDao abstract fun speakerDao(): SpeakerDao abstract fun sessionSpeakerJoinDao(): SessionSpeakerJoinDao }
  • 70. var db = Room.databaseBuilder( context, TdcDatabase::class.java) .build() var sessionDao = db.sessionDao() val session = Session(/* init */) val id = sessionDao.insert(session) sessionDao.sessionsByModality(eventId, modalityId)
 .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe { sessions -> // iterate over the sessions }
  • 84.
  • 86. • Você não precisa usar todos esses recursos no mesmo app… • Na verdade, você não precisa usar nenhum! • Mais importante do que saber quando USAR é saber quando NÃO USAR 😉 • Mas é essencial conhecer tópicos, saber seus prós e contras e utilizá-los adequadamente 💡
  • 87. Um desenvolvedor moderno… 2 Kotlin 3 Constraint Layout 4 Retrofit + OkHttp + GSON 5 RxJava e Coroutines 6 MVP ou MVVM 7 Architecture Components 8 Clean Architecture 9 Injeção de dependências 10 Testes 11 Firebase 1 Comunidade