Tuesday 27 November 2018

Android Architecture Components : Live Data + View Model

Hi ,

In previous posts , I have described the properties of View Model and Live Data . But if we use both together , that would be great for an individual application. So here I am going to share a demo where we can see that how both will work together .

Firstly I am creating one layout having one TextView inside , named  view_model_layout.xml -> 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textview7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="25sp"
        android:textColor="#085937"
        android:textStyle="bold"
        android:text="TextView" />


</RelativeLayout>

Now Let's create one view model class , named as : RandomNumViewModel.java :


package com.development.view_model_live_data;

import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;
import java.util.Random;

public class RandomNumViewModel extends ViewModel {

    MutableLiveData mMutableLiveData;

    public RandomNumViewModel() {
        mMutableLiveData = new MutableLiveData<>();
    }

    private int[] items = new int[]{1, 2, 3, 44, 65, 87, 22, 65, 87, 22, 90, 63, 4, 8, 50};
    private Random random = new Random();
    /**
     * mRandomNumber , this variable should retain its value,
     * on configuration change
     */
    private int mRandomNumber = 0;

    /**
     * used to create a random number from array
     * @return
     */
    public int createNumber(){
        mRandomNumber = items[random.nextInt(items.length)];

        return mRandomNumber;
    }

    /**
     * used to get the random number
     * @return
     * @param txt
     */
    /**
     * Observe the random number
     */
    public MutableLiveData getRandArrayElement(){
        if(mRandomNumber == 0){
            mRandomNumber = createNumber();
        }
        mMutableLiveData.setValue(mRandomNumber);
        return  mMutableLiveData;
    }
}


And the Activity class will only be observe the changed value of mRandomNumber , let's have a look on Activity class, named ViewLiveDemoActivity.java:

package com.development.view_model_live_data;

import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import com.development.R;

public class ViewLiveDemoActivity extends AppCompatActivity {
    TextView txt;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.view_model_layout);
        txt  = (TextView)findViewById(R.id.textview7);
        RandomNumViewModel randomNumViewModel = ViewModelProviders.of(this).get(RandomNumViewModel.class);
        randomNumViewModel.getRandArrayElement().observe(this, new Observer() {
            @Override
            public void onChanged(@Nullable Object o) {
                txt.setText(""+ o);
            }
        });
    }
}

Here you can see that , activity class only notify when variable value has been changed , and this is done by Live Data concept . If we rotate our device , then the value of variable will not be changed , this concept has been done by View Model . I have attached the screenshots for portrait and landscape modes for better understanding :

 Portrait Mode


Landscape Mode






Here in above images you can see that the variable value remains same after the rotation of device . And this all has been done both using Live Data +View Model . You can take this code and run it by yourself  . Happy Coding :) 

Tuesday 6 November 2018

Android Architecture Components : Live Data

Hi ,

In my previous post , I have described about ViewModel , and in this post I will explain about Live Data .Below are some properties of Live Data :


  •  Made it easy to update the UI data
  •  Observable Data holder class
  •  We need to observe Live Data , from the app's component's in onCreate()
  •  Keeps the UI updated , if value has been change of the data
  •  Automatically destroyed , when the associated LifeCycle Owner has been destroyed
  •  During data fetching from n/w or DB ,No crashes due to stop activity
  •  Can be shared by multiple resources
  •  Case:1 when the activity is in pause /stop state the activity will stop to observe the LiveData
  •  Case:2 when the activity is destroyed , it will stop to oberver the LiveData
  •  LiveData will only be observed by the activity , when it is in active state


So Live Data is a simple Data Type , having the capability to notify its observer when its value has been changed.
Live Data only notify the observer , when activity is in active state , so it prevents many crashes due to network call etc.

Before start let's take a look on- 

Mutable Data : Since Live Data , does not provide any public method to updated the Stored Data , we used its sub class,
this class provides us 2 methods:
  1. postValue()
  2. setValue()
setValue() method must be called from the main thread. 
But if you need set a value from a background thread, postValue() should be used.

Now let's take a look on Live Data simple demo , after this post I will explain demo for ViewModel+Live Data , as Live Data is best suited with view model.

So here I am taking one layout with one button and one text-view , on clicking that button , we are showing some random number on text-view , by using Live Data.

The layout which I am creating is named as : live_data_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">

<TextView
android:id="@+id/text_live_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Random"/>

</LinearLayout>


Now check the java file for activity class named as : LiveDataDemoActivity.java

package com.development.live_data;

import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.Observer;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.development.R;

import java.util.Random;

public class LiveDataDemoActivity extends AppCompatActivity {
private MutableLiveData mMutableLiveData;
private TextView mTextView;
private Button mButton;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.live_data_layout);
mTextView = (TextView) findViewById(R.id.text_live_data);
mButton = (Button) findViewById(R.id.button);
mMutableLiveData = new MutableLiveData<>();

/**
* Observe the random number
*/
mMutableLiveData.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
mTextView.setText(s);
}
});

/**
* Click on button
*/
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Random random = new Random();
mMutableLiveData.setValue("Random Int: " + random.nextInt());
}
});
}
}

Here you can see, that on click on the button , I am setting the data using Mutable Live Data setValue() , not using setText() of Text-view . Run the code and enjoy.

Benefit of using this method is , it will only update the text-view when activity is in active mode , otherwise not . So it is very useful to prevent memory leakage , application crashing etc.

 That's it .Happy Coding :)





Android Architecture Components : View Model

Hi ,
Today I am going to share another demo in Android architecture series i.e. View Model  . Firstly let me explain a short introduction of View Model:

  • Survives Configuration changes i.e. Screen-rotation
  • Not same as onSaveInstanceState (it is used to store small amount of data)
  • View Model used for large data such as :Bitmap or user list
  • store and manage UI related data
  • Destroyed only if the user activity is completely destroyed, in onCleared()
  • Communication layer between DB and UI
For more understanding , please refer : Android Developer View Model


So as I previously said, View Model is used to retain the data of configuration changes. So here I am going to explain a demo code , to check that View Model is really helpful to retain data while configuration changes (switching between landscape and portrait mode) or not .

In my demo code , I am taking one integer array , and getting one random number from that array .That random number will show on text-view. I will take 2 text-views , to hold the random number fetching from integer array. Among these two text-views , one will show the number normally while configuration changes and other text-view will show the number using view-model.So let's start:

-> Firstly I am adding following dependencies in build.gradle(app) file :

implementation "android.arch.lifecycle:runtime:1.1.1"
implementation "android.arch.lifecycle:extensions:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"

-> Take one layout named : view_model_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textview7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="25sp"
        android:textColor="#085937"
        android:textStyle="bold"
        android:text="TextView" />

    <TextView
        android:id="@+id/textview8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textview7"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:textSize="25sp"
        android:textColor="#085937"
        android:textStyle="bold"
        android:text="TextView" />

</RelativeLayout>



-> Before moving to activity java class, I have sub-classed , ViewModel class , with name :
RandomNumViewModel.java  , please take a look on code:

package com.development.view_model;

import android.arch.lifecycle.ViewModel;

import java.util.Random;

public class RandomNumViewModel extends ViewModel {

private int[] items = new int[]{1, 2, 3, 44, 65, 87, 22, 65, 87, 22, 90, 63, 4, 8, 50};

private Random random = new Random();

/**
* mRandomNumber , this variable should retain its value,
* on configuration change
*/
private int mRandomNumber = 0;


/**
* used to create a random number from array
* @return
*/
public int createNumber(){
mRandomNumber = items[random.nextInt(items.length)];
return mRandomNumber;
}


/**
* used to get the random number
* @return
*/
public int getRandArrayElement(){
if(mRandomNumber == 0){
mRandomNumber = createNumber();
return mRandomNumber;
}else{
return mRandomNumber;
}
}

}


-> Now take a look on my java file , I have named it as : ViewModelActivity.java

package com.development.view_model;

import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

import com.development.R;

import java.util.Random;

public class ViewModelActivity extends AppCompatActivity {
TextView txt,txt1;
private int[] items = new int[]{1, 2, 3, 44, 65, 87, 22, 65, 87, 22, 90, 63, 4, 8, 50};
private Random random = new Random();

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_model_layout);
txt = (TextView)findViewById(R.id.textview7);
txt1 = (TextView)findViewById(R.id.textview8);
int num = getRandArrayElement();

/**
* it's value should change on configuration change
*/
txt.setText(""+num); // normal way to set data on textview


/**
* Setting textview using View Model
* it's value should retain on configuration change
*/
RandomNumViewModel randomNumViewModel =
ViewModelProviders.of(this).get(RandomNumViewModel.class);

int num1 = randomNumViewModel.getRandArrayElement();

txt1.setText(""+num1);
}

public int getRandArrayElement(){
return items[random.nextInt(items.length)];
}
}


That's it , build and run the code, you can check that the value of one text-view will change , but value of another text-view will not change , while configuration changes (switching between landscape and portrait mode) , I have run my code , you can check the screen shots for various steps of screen-rotation:







       Portrait Mode

     



 Landscape Mode









Here in above screenshots, we can clearly see , that the second text-view , which is using View-Model , to show (retain) the number value , doesn't change while screen-rotation , but the first one changes its value. 

Advanced Kotlin Coroutines : Introduction

 Hi,  Today I am unwraping the topic in Kotin world i.e. Coroutine . If you want to get started with Kotlin coroutine and ease your daily de...