Android Architecture Components in Action
@derohimat
@esafirm
BRIEF HISTORY
* Versi saya.
What is Android Architecture Components (AAC) ?
A new collection of libraries that help you design robust, testable, and maintainable apps for managing your UI components lifecycle and handling data persistence . — developer.android.com
Room
The Problem
What is Room?
The Room persistence library provides an abstraction layer over SQLite to allow for more robust database access while harnessing the full power of SQLite.
Room is a part of Architecture Components, which means it works really well with ViewModel, LiveData and Paging (but does not depend on those modules!)
Introduced in Google I/O 2017.
Major Component of Room
Room architecture diagram
@Entity
Entity: Represents a table within the database.
Sample for @Entity
@Entity�public class User {� @PrimaryKey� private int uid;� @ColumnInfo(name = "first_name")� private String firstName;� @ColumnInfo(name = "last_name")� private String lastName;� // Getters and setters are ignored for brevity,� // but they're required for Room to work.�}
User.java
@Dao
DAO (Data Access Object) : Contains the methods used for accessing the database.
Sample for @Dao
@Dao�public interface UserDao {� @Query("SELECT * FROM user")� List<User> getAll();� @Query("SELECT * FROM user WHERE uid IN (:userIds)")� List<User> loadAllByIds(int[] userIds);� @Query("SELECT * FROM user WHERE first_name LIKE :first AND last_name LIKE :last LIMIT 1")� User findByName(String first, String last);� @Insert� void insertAll(User... users);� @Delete� void delete(User user);�}
UserDao.java
@Database
Database: Contains the database holder and serves as the main access point for the underlying connection to your app's persisted, relational data.
The class that's annotated with @Database should satisfy the following conditions:
At runtime, you can acquire an instance of Database by calling Room.databaseBuilder() or Room.inMemoryDatabaseBuilder().
Sample for @Database
@Database(entities = {User.class}, version = 1)�public abstract class AppDatabase extends RoomDatabase {� public abstract UserDao userDao();�}
AppDatabase.java
After creating the files above, you get an instance of the created database using the following code:
AppDatabase db = Room.databaseBuilder(getApplicationContext(),� AppDatabase.class, "database-name").build();
Another Annotations in Room
Migration SQLite to Room
ViewModel
The Problem
The Problem
What is ViewModel?
A class that designed to hold and manage UI-related data in a life-cycle conscious way
Simple Implementation
class ScoreViewModel : ViewModel() {� var teamScore: Int = 0� fun add(){� teamScore += 1� }�}
Simple Implementation
class ScoreActivity : AppCompatActivity() {� val viewModel get() =� ViewModelProviders.of(this).get(ScoreViewModel::class.java)�� fun bindView() {� textViewScore.setText(viewModel.teamScore)� btnAdd.setOnClickListener {� viewModel.add()� textViewScore.setText(viewModel.teamScore)� }� }�}
ViewModel initialization
// this could be a FragmentActivity or Fragment
val viewModel get() =� ViewModelProviders.of(this).get(ScoreViewModel::class.java)
Custom constructor
class ScoreVmFactory constructor(val team: String): ViewModelProvider.Factory {�� override fun <T : ViewModel> create(modelClass: Class<T>): T {� return if (modelClass.isAssignableFrom(ScoreViewModel::class.java!!)) {� ScoreViewModel(team) as T� } else {� throw IllegalArgumentException("ViewModel Not Found")� }� }��}
Share data between Fragments
class ScoreViewModel : ViewModel() {� var teamScore: Int = 0�}��class FragmentA : Fragment() {� val teamScore by lazy {� ViewModelProviders.of(requreActivity()).get(ScoreViewModel::class.java)� }�}��class FragmentB : Fragment() {� val teamScore by lazy {� ViewModelProviders.of(requreActivity()).get(ScoreViewModel::class.java)� }�}
ViewModel and Context
ViewModel vs onSaveInstanceState()
DataBinding support!
<CheckBox� android:id="@+id/rememberMeCheckBox"� android:checked="@{viewmodel.rememberMe}"� android:onCheckedChanged="@{() -> viewmodel.rememberMeChanged()}" />
val userModel = ViewModelProviders.of(this).get(UserModel.class)�val binding: UserBinding = DataBindingUtil.setContentView(this, R.layout.user)�// Assign the component to a property in the binding class.�binding.viewmodel = userModel
ViewModel highlight
LiveData
The Problems
What is LiveData?
LiveData is an lifecycle aware observable data holder class.
Observable?
Simple Implementation
class ScoreViewModel : ViewMode() {� val currentName by lazy { MutableLiveData<String>()� .also { it.setValue("100") } � }�}��class ScoreActivity : AppComponentActivity() {� fun onCreate(savedInstanceState: Bundle) {� // ViewModel is created somewhere� viewModel.currentName.observe(this, Observer {� // do something with currentName� })� }�}
Updating LiveData
val score = MutableLiveData<String>()��// Do this if sure you're on UI thread�viewModel.score.setValue("100")��// Otherwise just use this�viewModel.score.postValue("100")
Extending LiveData
class StockLiveData(symbol: String) : LiveData<BigDecimal>() {� private val stockManager: StockManager = StockManager(symbol)�� private val listener = object : SimplePriceListener() {� fun onPriceChanged(price: BigDecimal) {� setValue(price)� }� }�� override fun onActive() {� stockManager.requestPriceUpdates(listener)� }�� override fun onInactive() {� stockManager.removeUpdates(listener)� }�}
LiveData’s life
Transformations
val userNames: LiveData<String> = Transformations� .map(_, user -> {user.name});
MediatorLiveData
val updateCountLiveData = MediatorLiveData<Int>()��updateCountLiveData.addSource(score) { _ ->� updateCountLiveData.value?.plus(1)�}��updateCountLiveData.addSource(forecast) { _ ->� updateCountLiveData.value?.plus(1)�}
Room Support
@Query("SELECT * FROM weather WHERE date = :date")� LiveData<WeatherEntry> getWeatherByDate(Date date);
DataBinding Support
<CheckBox� android:id="@+id/rememberMeCheckBox"� android:checked="@{viewmodel.rememberMe}"� android:onCheckedChanged="@{() -> viewmodel.rememberMeChanged()}" />
LiveData highlight
References
THANK YOU