SlideShare a Scribd company logo
1 of 35
Download to read offline
15 Agustus 2017
Android Architecture Components
Facebook DevCircle Yoygakarta #2
./siapasaya
Pratama Nur Wijaya
Android Developer & Kotlin Enthusiast

Co Founder @KotlinID



t.me/KotlinID
github.com/pratamawijaya
pratamwijaya.com
“Sebuah kisah tentang perjalanan seorang Android
Development”
✤ Menulis logic kode hanya didalam activity/fragment
🍝
✤ Tidak mengenal yang namanya design pattern 🙈
✤ Hanya mengikuti/manut tutorial yang ada di web,
misal AndroidHive
✤ Selama app jalan dan client bahagia, kenapa tidak ? 🐯
“Semakin sering aktif diforum dan baca hal-hal yang
menarik, dan mulai mencoba hal baru”
…Perubahan…
✤ Mulai mengenal pattern
✤ MVP, Singleton, Repository Pattern
✤ Clean Architecture 😎
✤ Unit Test 🎸
✤ Semua itu dari community https://github.com/
googlesamples/android-architecture
✤ Belum ada standarisasi yang jelas
Masalahnya
Android Architecture Components
(AAC)
Apa itu AAC
✤ Library
✤ Guidelines
✤ Tujuan dari AAC
✤ Standarisasi
✤ Mengurangi Boilerplate
✤ Mengurangi kode yang berulang
Masalah yang diselesaikan oleh AAC
✤ Lifecycle
✤ Persistence & Offline support
Masalah yang diselesaikan oleh AAC
✤ Lifecycle
✤ LifecycleOwner + LifecycleObserver
✤ Live Data
✤ ViewModel
✤ Persistence & Offline Support
✤ Room
Menambahkan dependency
• compile "android.arch.lifecycle:runtime:1.0.0-alpha5"
• compile "android.arch.lifecycle:extensions:1.0.0-alpha5"
• annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha5"
Android Activity Lifecycle
LifecycleObserver
Sebelum
public class MyLocationListener {
!//
public void start() {
Log.d(TAG, "start: ");
locationManager = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
MIN_TIME_UPDATE, MIN_DISTANCE_UPDATE, listener);
!// Force an update with the last location, if available.
Location lastLocation = locationManager.getLastKnownLocation(
LocationManager.GPS_PROVIDER);
if (lastLocation !!= null) {
listener.onLocationChanged(lastLocation);
}
}
public void stop() {
Log.d(TAG, "stop: ");
if (locationManager !!= null) {
locationManager.removeUpdates(listener);
}
}
}
Sebelum
public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks, LocationListener {
@Override
protected void onStart() {
super.onStart();
requestPermissionLocation();
}
@AfterPermissionGranted(RC_LOCATION)
private void requestPermissionLocation() {
String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
if (EasyPermissions.hasPermissions(this, perms)) {
myLocationListener.start();
} else {
EasyPermissions.requestPermissions(this, "Need permission location",
RC_LOCATION, perms);
}
}
@Override
protected void onStop() {
super.onStop();
myLocationListener.stop();
}
}
Sesudah
public class MyLocationListenerObserver implements LifecycleObserver {
public MyLocationListenerObserver(Context context, LifecycleOwner lifecycle, LocationListener listener) {
!// ….
!// observe to lifecycle
this.lifecycle.getLifecycle().addObserver(this);
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
void start() {
Log.d(TAG, "start: ");
locationManager = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_UPDATE, MIN_DISTANCE_UPDATE, mListener);
!// Force an update with the last location, if available.
Location lastLocation = locationManager.getLastKnownLocation(
LocationManager.GPS_PROVIDER);
if (lastLocation !!= null) {
mListener.onLocationChanged(lastLocation);
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
void stop() {
Log.d(TAG, "stop: ");
if (locationManager !!= null) {
locationManager.removeUpdates(mListener);
locationManager = null;
}
}
}
Sesudah
public class MainLifecyleActivity extends LifecycleActivity implements LocationListener,
EasyPermissions.PermissionCallbacks {
private static final String TAG = MainLifecyleActivity.class.getSimpleName();
private static final int RC_LOCATION = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_lifecyle);
requestPermissionLocation();
}
@AfterPermissionGranted(RC_LOCATION)
private void requestPermissionLocation() {
String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
if (EasyPermissions.hasPermissions(this, perms)) {
new MyLocationListenerObserver(this, this, this);
} else {
EasyPermissions.requestPermissions(this, "Need permission location",
RC_LOCATION, perms);
}
}
}
LiveData
Digunakan untuk membungkus (encapsulate) data, dan
mengijinkan data untuk di observe, mirip seperti observable
(RxJava) tapi lebih respect dengan activity lifecycle
LiveData<User>
Location LiveData
public class LocationLiveData extends LiveData<Location> {
private static LocationLiveData sLocationLiveData;
@MainThread
public static LocationLiveData get(Context context) {
if (sLocationLiveData !== null) {
sLocationLiveData = new LocationLiveData(context);
}
return sLocationLiveData;
}
private LocationLiveData(Context context) {
listener = new SimpleListener();
locationManager = (LocationManager) context.getSystemService(
Context.LOCATION_SERVICE);
}
@Override
protected void onActive() {
super.onActive();
Log.d(TAG, "onActive: ");
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
}
@Override
protected void onInactive() {
super.onInactive();
Log.d(TAG, "onInactive: ");
locationManager.removeUpdates(listener);
}
}
Location LiveData
package com.pratamawijaya.androidlifecycleownerobserver
import android.arch.lifecycle.LifecycleActivity
import android.arch.lifecycle.Observer
import android.location.Location
import android.os.Bundle
import android.util.Log
import com.pratamawijaya.androidlifecycleownerobserver.livedata.LocationLiveData
class MainLiveDataActivity : LifecycleActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main_live_data)
LocationLiveData.get(this).observe(this,
Observer<Location> {
location !->
Log.d(TAG, "onChanged: " + location!?.latitude)
})
}
companion object {
private val TAG = MainLifecyleActivity!::class.java.simpleName
}
}
ViewModel
Penyelamat data saat orientasi device berubah
ViewModel Lifecycle
ViewModel
class ProMatchesViewModel : ViewModel() {
@Inject
lateinit var matchesRepo: MatchesRepository
private var liveMatchesData: LiveData<List<Matches!>>? = null
init {
BaseApp.appComponent.inject(this)
}
fun getProMatchesData(): LiveData<List<Matches!>> {
if (liveMatchesData !== null) {
liveMatchesData = MutableLiveData<List<Matches!>>()
liveMatchesData = matchesRepo.getProMatches()
}
return liveMatchesData as LiveData<List<Matches!>>
}
override fun onCleared() {
super.onCleared()
d { "vm cleared" }
}
}
https:!//github.com/pratamawijaya/DotaTournamentMatch-ArchComponentAndroid
ViewModel
class MainActivity : LifecycleActivity() {
private lateinit var proMatchesVM: ProMatchesViewModel
private lateinit var rvMatches: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
proMatchesVM = ViewModelProviders.of(this).get(ProMatchesViewModel!::class.java)
rvMatches = findViewById(R.id.rvMatches)
rvMatches.layoutManager = LinearLayoutManager(this)
proMatchesVM.getProMatchesData().observe(this, Observer {
result !->
LastAdapter(result!!!, BR.matches)
.map<Matches>(R.layout.layout_item_matches)
.into(rvMatches)
})
}
}
https:!//github.com/pratamawijaya/DotaTournamentMatch-ArchComponentAndroid
Room
Sudah saatnya melupakan kepedihan ketika membuat
database dengan SQLite 😂
Abstraction layer untuk SQLite
Dependency
• compile "android.arch.persistence.room:runtime:1.0.0-alpha5"
• annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha5"
• compile "android.arch.persistence.room:runtime:1.0.0-alpha5"
• kapt "android.arch.persistence.room:compiler:1.0.0-alpha5"
Kotlin Version
Room Components
✤ Database (Komponen untuk membuat database)
✤ Entity (Komponen yang merepresentasikan database row kedalam
class)
✤ DAO (Interface yang didalamnya method untuk akses database)
Entity
package id.kotlin.sample.room.data
import android.arch.persistence.room.ColumnInfo
import android.arch.persistence.room.Entity
import android.arch.persistence.room.PrimaryKey
@Entity
data class User constructor(@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "user_id") val id: Long,
@ColumnInfo(name = "first_name") val firstName: String,
@ColumnInfo(name = "last_name") val lastName: String)
https:!//github.com/KotlinID/android-room-kotlin
DAO
package id.kotlin.sample.room.data
import android.arch.persistence.room.Dao
import android.arch.persistence.room.Delete
import android.arch.persistence.room.Insert
import android.arch.persistence.room.OnConflictStrategy
import android.arch.persistence.room.Query
import android.arch.persistence.room.Update
@Dao
interface UserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun createUser(user: User)
@Query("SELECT * FROM User")
fun findAll(): List<User>
@Update
fun updateUser(user: User)
@Delete
fun deleteUser(user: User)
}
https:!//github.com/KotlinID/android-room-kotlin
Database
package id.kotlin.sample.room.data
import android.arch.persistence.room.Database
import android.arch.persistence.room.RoomDatabase
@Database(entities = arrayOf(User!::class), version = 1)
abstract class Database : RoomDatabase() {
abstract fun userDao(): UserDao
}
https:!//github.com/KotlinID/android-room-kotlin
CRUD
package id.kotlin.sample.room.main
class MainActivity : AppCompatActivity() {
private fun getUsers(): List<User> {
val dao = Room.database.userDao()
val users = dao.findAll()
if (users.isEmpty()) {
val user = User(getId(), "Budi", "Oktaviyan Suryanto")
dao.createUser(user)
return dao.findAll()
}
return users
}
}
https:!//github.com/KotlinID/android-room-kotlin
CRUD
package id.kotlin.sample.room.create
class AddActivity : AppCompatActivity() {
private fun addButtonListener() {
btnAdd.setOnClickListener {
val firstName = editFirstname.text.toString()
val lastName = editLastname.text.toString()
if (firstName.isNotEmpty().and(lastName.isNotEmpty())) {
async(UI) {
bg {
val dao = Room.database.userDao()
val user = User(getId(), firstName, lastName)
dao.createUser(user)
}
setResult(RESULT_OK)
finish()
}
} else {
toast(ctx.getString(R.string.message_create_user))
}
}
}
}
https:!//github.com/KotlinID/android-room-kotlin
CRUD
class EditActivity : AppCompatActivity() {
private fun editButtonListener() {
if (firstName.isNotEmpty().and(lastName.isNotEmpty())) {
async(UI) {
bg {
val dao = Room.database.userDao()
val user = User(data.id, firstName, lastName)
dao.updateUser(user)
}
setResult(RESULT_OK)
finish()
}
}
}
}
https:!//github.com/KotlinID/android-room-kotlin
Reference
✤ https://developer.android.com/topic/libraries/architecture/index.html
✤ https://blog.stylingandroid.com/architecture-components-lifecycle/
✤ https://github.com/KotlinID
✤ https://codelabs.developers.google.com/codelabs/android-lifecycles
✤ https://codelabs.developers.google.com/codelabs/android-persistence
✤ Thanks to Telegram Group @KotlinID @androidDevBdg

More Related Content

What's hot

Introduction to rx java for android
Introduction to rx java for androidIntroduction to rx java for android
Introduction to rx java for androidEsa Firman
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
RxJava from the trenches
RxJava from the trenchesRxJava from the trenches
RxJava from the trenchesPeter Hendriks
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaFabio Collini
 
Reactive programming with RxAndroid
Reactive programming with RxAndroidReactive programming with RxAndroid
Reactive programming with RxAndroidSavvycom Savvycom
 
Android Loaders : Reloaded
Android Loaders : ReloadedAndroid Loaders : Reloaded
Android Loaders : Reloadedcbeyls
 
Reactive Android: RxJava and beyond
Reactive Android: RxJava and beyondReactive Android: RxJava and beyond
Reactive Android: RxJava and beyondFabio Tiriticco
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsLeonardo Borges
 
Loaders (and why we should use them)
Loaders (and why we should use them)Loaders (and why we should use them)
Loaders (and why we should use them)Michael Pustovit
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaRick Warren
 
Reactive Programming on Android - RxAndroid - RxJava
Reactive Programming on Android - RxAndroid - RxJavaReactive Programming on Android - RxAndroid - RxJava
Reactive Programming on Android - RxAndroid - RxJavaAli Muzaffar
 
Testing Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKTesting Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKFabio Collini
 
RxJava applied [JavaDay Kyiv 2016]
RxJava applied [JavaDay Kyiv 2016]RxJava applied [JavaDay Kyiv 2016]
RxJava applied [JavaDay Kyiv 2016]Igor Lozynskyi
 
Reactive programming with RxJava
Reactive programming with RxJavaReactive programming with RxJava
Reactive programming with RxJavaJobaer Chowdhury
 

What's hot (20)

Introduction to rx java for android
Introduction to rx java for androidIntroduction to rx java for android
Introduction to rx java for android
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
RxJava from the trenches
RxJava from the trenchesRxJava from the trenches
RxJava from the trenches
 
RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
 
Reactive Java (33rd Degree)
Reactive Java (33rd Degree)Reactive Java (33rd Degree)
Reactive Java (33rd Degree)
 
Rxjava meetup presentation
Rxjava meetup presentationRxjava meetup presentation
Rxjava meetup presentation
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJava
 
Reactive programming with RxAndroid
Reactive programming with RxAndroidReactive programming with RxAndroid
Reactive programming with RxAndroid
 
Android Loaders : Reloaded
Android Loaders : ReloadedAndroid Loaders : Reloaded
Android Loaders : Reloaded
 
RxJava Applied
RxJava AppliedRxJava Applied
RxJava Applied
 
Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)
 
Introduction to Reactive Java
Introduction to Reactive JavaIntroduction to Reactive Java
Introduction to Reactive Java
 
Reactive Android: RxJava and beyond
Reactive Android: RxJava and beyondReactive Android: RxJava and beyond
Reactive Android: RxJava and beyond
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
 
Loaders (and why we should use them)
Loaders (and why we should use them)Loaders (and why we should use them)
Loaders (and why we should use them)
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
Reactive Programming on Android - RxAndroid - RxJava
Reactive Programming on Android - RxAndroid - RxJavaReactive Programming on Android - RxAndroid - RxJava
Reactive Programming on Android - RxAndroid - RxJava
 
Testing Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKTesting Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UK
 
RxJava applied [JavaDay Kyiv 2016]
RxJava applied [JavaDay Kyiv 2016]RxJava applied [JavaDay Kyiv 2016]
RxJava applied [JavaDay Kyiv 2016]
 
Reactive programming with RxJava
Reactive programming with RxJavaReactive programming with RxJava
Reactive programming with RxJava
 

Similar to Android architecture component - FbCircleDev Yogyakarta Indonesia

Architecture Components
Architecture ComponentsArchitecture Components
Architecture ComponentsSang Eel Kim
 
Android Architecture Components
Android Architecture ComponentsAndroid Architecture Components
Android Architecture ComponentsBurhanuddinRashid
 
Architecture components - IT Talk
Architecture components - IT TalkArchitecture components - IT Talk
Architecture components - IT TalkConstantine Mars
 
Architecture Components
Architecture Components Architecture Components
Architecture Components DataArt
 
What's Coming in Spring 3.0
What's Coming in Spring 3.0What's Coming in Spring 3.0
What's Coming in Spring 3.0Matt Raible
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsHassan Abid
 
Functional Reactive Programming in the Netflix API
Functional Reactive Programming in the Netflix APIFunctional Reactive Programming in the Netflix API
Functional Reactive Programming in the Netflix APIC4Media
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolboxShem Magnezi
 
Petcube epic battle: architecture vs product. UA Mobile 2017.
Petcube epic battle: architecture vs product. UA Mobile 2017.Petcube epic battle: architecture vs product. UA Mobile 2017.
Petcube epic battle: architecture vs product. UA Mobile 2017.UA Mobile
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionChristian Panadero
 
My way to clean android (EN) - Android day salamanca edition
My way to clean android (EN) - Android day salamanca editionMy way to clean android (EN) - Android day salamanca edition
My way to clean android (EN) - Android day salamanca editionChristian Panadero
 
Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017Matt Raible
 
Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020
Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020
Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020AWSKRUG - AWS한국사용자모임
 
DWR, Hibernate and Dojo.E - A Tutorial
DWR, Hibernate and Dojo.E - A TutorialDWR, Hibernate and Dojo.E - A Tutorial
DWR, Hibernate and Dojo.E - A Tutorialjbarciauskas
 
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...César Hernández
 
Android Automated Testing
Android Automated TestingAndroid Automated Testing
Android Automated Testingroisagiv
 
Architecture Components In Real Life Season 2
Architecture Components In Real Life Season 2Architecture Components In Real Life Season 2
Architecture Components In Real Life Season 2Somkiat Khitwongwattana
 

Similar to Android architecture component - FbCircleDev Yogyakarta Indonesia (20)

Architecture Components
Architecture ComponentsArchitecture Components
Architecture Components
 
Android Architecture Components
Android Architecture ComponentsAndroid Architecture Components
Android Architecture Components
 
Architecture components - IT Talk
Architecture components - IT TalkArchitecture components - IT Talk
Architecture components - IT Talk
 
Architecture Components
Architecture Components Architecture Components
Architecture Components
 
What's Coming in Spring 3.0
What's Coming in Spring 3.0What's Coming in Spring 3.0
What's Coming in Spring 3.0
 
Android best practices
Android best practicesAndroid best practices
Android best practices
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture Components
 
Functional Reactive Programming in the Netflix API
Functional Reactive Programming in the Netflix APIFunctional Reactive Programming in the Netflix API
Functional Reactive Programming in the Netflix API
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolbox
 
Petcube epic battle: architecture vs product. UA Mobile 2017.
Petcube epic battle: architecture vs product. UA Mobile 2017.Petcube epic battle: architecture vs product. UA Mobile 2017.
Petcube epic battle: architecture vs product. UA Mobile 2017.
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca edition
 
My way to clean android (EN) - Android day salamanca edition
My way to clean android (EN) - Android day salamanca editionMy way to clean android (EN) - Android day salamanca edition
My way to clean android (EN) - Android day salamanca edition
 
Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017
 
Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020
Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020
Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020
 
DWR, Hibernate and Dojo.E - A Tutorial
DWR, Hibernate and Dojo.E - A TutorialDWR, Hibernate and Dojo.E - A Tutorial
DWR, Hibernate and Dojo.E - A Tutorial
 
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
 
Android Automated Testing
Android Automated TestingAndroid Automated Testing
Android Automated Testing
 
Architecture Components In Real Life Season 2
Architecture Components In Real Life Season 2Architecture Components In Real Life Season 2
Architecture Components In Real Life Season 2
 

Recently uploaded

Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 

Recently uploaded (20)

Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 

Android architecture component - FbCircleDev Yogyakarta Indonesia

  • 1. 15 Agustus 2017 Android Architecture Components Facebook DevCircle Yoygakarta #2
  • 2. ./siapasaya Pratama Nur Wijaya Android Developer & Kotlin Enthusiast
 Co Founder @KotlinID
 
 t.me/KotlinID github.com/pratamawijaya pratamwijaya.com
  • 3. “Sebuah kisah tentang perjalanan seorang Android Development”
  • 4. ✤ Menulis logic kode hanya didalam activity/fragment 🍝 ✤ Tidak mengenal yang namanya design pattern 🙈 ✤ Hanya mengikuti/manut tutorial yang ada di web, misal AndroidHive ✤ Selama app jalan dan client bahagia, kenapa tidak ? 🐯
  • 5. “Semakin sering aktif diforum dan baca hal-hal yang menarik, dan mulai mencoba hal baru” …Perubahan…
  • 6. ✤ Mulai mengenal pattern ✤ MVP, Singleton, Repository Pattern ✤ Clean Architecture 😎 ✤ Unit Test 🎸
  • 7. ✤ Semua itu dari community https://github.com/ googlesamples/android-architecture ✤ Belum ada standarisasi yang jelas Masalahnya
  • 9. Apa itu AAC ✤ Library ✤ Guidelines ✤ Tujuan dari AAC ✤ Standarisasi ✤ Mengurangi Boilerplate ✤ Mengurangi kode yang berulang
  • 10. Masalah yang diselesaikan oleh AAC ✤ Lifecycle ✤ Persistence & Offline support
  • 11. Masalah yang diselesaikan oleh AAC ✤ Lifecycle ✤ LifecycleOwner + LifecycleObserver ✤ Live Data ✤ ViewModel ✤ Persistence & Offline Support ✤ Room
  • 12. Menambahkan dependency • compile "android.arch.lifecycle:runtime:1.0.0-alpha5" • compile "android.arch.lifecycle:extensions:1.0.0-alpha5" • annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha5"
  • 15. Sebelum public class MyLocationListener { !// public void start() { Log.d(TAG, "start: "); locationManager = (LocationManager) context .getSystemService(Context.LOCATION_SERVICE); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_UPDATE, MIN_DISTANCE_UPDATE, listener); !// Force an update with the last location, if available. Location lastLocation = locationManager.getLastKnownLocation( LocationManager.GPS_PROVIDER); if (lastLocation !!= null) { listener.onLocationChanged(lastLocation); } } public void stop() { Log.d(TAG, "stop: "); if (locationManager !!= null) { locationManager.removeUpdates(listener); } } }
  • 16. Sebelum public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks, LocationListener { @Override protected void onStart() { super.onStart(); requestPermissionLocation(); } @AfterPermissionGranted(RC_LOCATION) private void requestPermissionLocation() { String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}; if (EasyPermissions.hasPermissions(this, perms)) { myLocationListener.start(); } else { EasyPermissions.requestPermissions(this, "Need permission location", RC_LOCATION, perms); } } @Override protected void onStop() { super.onStop(); myLocationListener.stop(); } }
  • 17. Sesudah public class MyLocationListenerObserver implements LifecycleObserver { public MyLocationListenerObserver(Context context, LifecycleOwner lifecycle, LocationListener listener) { !// …. !// observe to lifecycle this.lifecycle.getLifecycle().addObserver(this); } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) void start() { Log.d(TAG, "start: "); locationManager = (LocationManager) context .getSystemService(Context.LOCATION_SERVICE); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_UPDATE, MIN_DISTANCE_UPDATE, mListener); !// Force an update with the last location, if available. Location lastLocation = locationManager.getLastKnownLocation( LocationManager.GPS_PROVIDER); if (lastLocation !!= null) { mListener.onLocationChanged(lastLocation); } } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) void stop() { Log.d(TAG, "stop: "); if (locationManager !!= null) { locationManager.removeUpdates(mListener); locationManager = null; } } }
  • 18. Sesudah public class MainLifecyleActivity extends LifecycleActivity implements LocationListener, EasyPermissions.PermissionCallbacks { private static final String TAG = MainLifecyleActivity.class.getSimpleName(); private static final int RC_LOCATION = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_lifecyle); requestPermissionLocation(); } @AfterPermissionGranted(RC_LOCATION) private void requestPermissionLocation() { String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}; if (EasyPermissions.hasPermissions(this, perms)) { new MyLocationListenerObserver(this, this, this); } else { EasyPermissions.requestPermissions(this, "Need permission location", RC_LOCATION, perms); } } }
  • 19. LiveData Digunakan untuk membungkus (encapsulate) data, dan mengijinkan data untuk di observe, mirip seperti observable (RxJava) tapi lebih respect dengan activity lifecycle LiveData<User>
  • 20. Location LiveData public class LocationLiveData extends LiveData<Location> { private static LocationLiveData sLocationLiveData; @MainThread public static LocationLiveData get(Context context) { if (sLocationLiveData !== null) { sLocationLiveData = new LocationLiveData(context); } return sLocationLiveData; } private LocationLiveData(Context context) { listener = new SimpleListener(); locationManager = (LocationManager) context.getSystemService( Context.LOCATION_SERVICE); } @Override protected void onActive() { super.onActive(); Log.d(TAG, "onActive: "); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener); } @Override protected void onInactive() { super.onInactive(); Log.d(TAG, "onInactive: "); locationManager.removeUpdates(listener); } }
  • 21. Location LiveData package com.pratamawijaya.androidlifecycleownerobserver import android.arch.lifecycle.LifecycleActivity import android.arch.lifecycle.Observer import android.location.Location import android.os.Bundle import android.util.Log import com.pratamawijaya.androidlifecycleownerobserver.livedata.LocationLiveData class MainLiveDataActivity : LifecycleActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main_live_data) LocationLiveData.get(this).observe(this, Observer<Location> { location !-> Log.d(TAG, "onChanged: " + location!?.latitude) }) } companion object { private val TAG = MainLifecyleActivity!::class.java.simpleName } }
  • 22. ViewModel Penyelamat data saat orientasi device berubah
  • 24. ViewModel class ProMatchesViewModel : ViewModel() { @Inject lateinit var matchesRepo: MatchesRepository private var liveMatchesData: LiveData<List<Matches!>>? = null init { BaseApp.appComponent.inject(this) } fun getProMatchesData(): LiveData<List<Matches!>> { if (liveMatchesData !== null) { liveMatchesData = MutableLiveData<List<Matches!>>() liveMatchesData = matchesRepo.getProMatches() } return liveMatchesData as LiveData<List<Matches!>> } override fun onCleared() { super.onCleared() d { "vm cleared" } } } https:!//github.com/pratamawijaya/DotaTournamentMatch-ArchComponentAndroid
  • 25. ViewModel class MainActivity : LifecycleActivity() { private lateinit var proMatchesVM: ProMatchesViewModel private lateinit var rvMatches: RecyclerView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) proMatchesVM = ViewModelProviders.of(this).get(ProMatchesViewModel!::class.java) rvMatches = findViewById(R.id.rvMatches) rvMatches.layoutManager = LinearLayoutManager(this) proMatchesVM.getProMatchesData().observe(this, Observer { result !-> LastAdapter(result!!!, BR.matches) .map<Matches>(R.layout.layout_item_matches) .into(rvMatches) }) } } https:!//github.com/pratamawijaya/DotaTournamentMatch-ArchComponentAndroid
  • 26. Room Sudah saatnya melupakan kepedihan ketika membuat database dengan SQLite 😂 Abstraction layer untuk SQLite
  • 27. Dependency • compile "android.arch.persistence.room:runtime:1.0.0-alpha5" • annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha5" • compile "android.arch.persistence.room:runtime:1.0.0-alpha5" • kapt "android.arch.persistence.room:compiler:1.0.0-alpha5" Kotlin Version
  • 28. Room Components ✤ Database (Komponen untuk membuat database) ✤ Entity (Komponen yang merepresentasikan database row kedalam class) ✤ DAO (Interface yang didalamnya method untuk akses database)
  • 29. Entity package id.kotlin.sample.room.data import android.arch.persistence.room.ColumnInfo import android.arch.persistence.room.Entity import android.arch.persistence.room.PrimaryKey @Entity data class User constructor(@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "user_id") val id: Long, @ColumnInfo(name = "first_name") val firstName: String, @ColumnInfo(name = "last_name") val lastName: String) https:!//github.com/KotlinID/android-room-kotlin
  • 30. DAO package id.kotlin.sample.room.data import android.arch.persistence.room.Dao import android.arch.persistence.room.Delete import android.arch.persistence.room.Insert import android.arch.persistence.room.OnConflictStrategy import android.arch.persistence.room.Query import android.arch.persistence.room.Update @Dao interface UserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun createUser(user: User) @Query("SELECT * FROM User") fun findAll(): List<User> @Update fun updateUser(user: User) @Delete fun deleteUser(user: User) } https:!//github.com/KotlinID/android-room-kotlin
  • 31. Database package id.kotlin.sample.room.data import android.arch.persistence.room.Database import android.arch.persistence.room.RoomDatabase @Database(entities = arrayOf(User!::class), version = 1) abstract class Database : RoomDatabase() { abstract fun userDao(): UserDao } https:!//github.com/KotlinID/android-room-kotlin
  • 32. CRUD package id.kotlin.sample.room.main class MainActivity : AppCompatActivity() { private fun getUsers(): List<User> { val dao = Room.database.userDao() val users = dao.findAll() if (users.isEmpty()) { val user = User(getId(), "Budi", "Oktaviyan Suryanto") dao.createUser(user) return dao.findAll() } return users } } https:!//github.com/KotlinID/android-room-kotlin
  • 33. CRUD package id.kotlin.sample.room.create class AddActivity : AppCompatActivity() { private fun addButtonListener() { btnAdd.setOnClickListener { val firstName = editFirstname.text.toString() val lastName = editLastname.text.toString() if (firstName.isNotEmpty().and(lastName.isNotEmpty())) { async(UI) { bg { val dao = Room.database.userDao() val user = User(getId(), firstName, lastName) dao.createUser(user) } setResult(RESULT_OK) finish() } } else { toast(ctx.getString(R.string.message_create_user)) } } } } https:!//github.com/KotlinID/android-room-kotlin
  • 34. CRUD class EditActivity : AppCompatActivity() { private fun editButtonListener() { if (firstName.isNotEmpty().and(lastName.isNotEmpty())) { async(UI) { bg { val dao = Room.database.userDao() val user = User(data.id, firstName, lastName) dao.updateUser(user) } setResult(RESULT_OK) finish() } } } } https:!//github.com/KotlinID/android-room-kotlin
  • 35. Reference ✤ https://developer.android.com/topic/libraries/architecture/index.html ✤ https://blog.stylingandroid.com/architecture-components-lifecycle/ ✤ https://github.com/KotlinID ✤ https://codelabs.developers.google.com/codelabs/android-lifecycles ✤ https://codelabs.developers.google.com/codelabs/android-persistence ✤ Thanks to Telegram Group @KotlinID @androidDevBdg