Sunday 11 December 2016

write immutable class in Java with example

How to write immutable class in Java

Some points we need to follow, which helps to make a class immutable in Java :

1. State of immutable object can not be modified after construction, any modification should result in new immutable object.
2. All fields of Immutable class should be final.
3. Class should be final in order to restrict sub-class for altering immutability of parent class.

So our immutable class have all private and final variables and a constructor to initialize the variables during object creation. All final variables can be initialized inside constructor only once during object creation that can't be changed latter. our immutable class does not provide setter method but have only getter method to access the initialized variables. 

Example

Simplest approach for making a class immutable, including it's making final class to avoid putting immutability at risk due to Inheritance and Polymorphism.



public final class Contacts {

    private final String name;
    private final String mobile;

    public Contacts(String name, String mobile) {
        this.name = name;
        this.mobile = mobile;
    }
  
    public String getName(){
        return name;
    }
  
    public String getMobile(){
        return mobile;
    }

}

Singleton design pattern and preventing its cloning

Singleton :- Singleton design pattern is used to create only single object of the class. we can say to avoid the multiple object creation and limiting the number of objects to one. 

Prevent Object Cloning :- We can prevent the object cloning of singleton class by implementing the Cloneable interface and forcefully throw an exception 'throw new CloneNotSupportedException();' inside overridden clone() methods as written in below example-   

public class MySingletonTest implements Cloneable {

 private static MySingletonTest mSingletonTest = null;

 private MySingletonTest() {

  System.out.println("Sanjaya verma");

 }

 public static MySingletonTest getInstance() {

  if (mSingletonTest == null) {

   mSingletonTest = new MySingletonTest();

  }

  return mSingletonTest;

 }


 @Override
 protected Object clone() throws CloneNotSupportedException {
 // Here forcefully throw an exception to prevent the object cloning

  throw new CloneNotSupportedException();

  //return super.clone();

 }



 public static void main(String[] args) {

  MySingletonTest t1=new MySingletonTest(); 

  try {

       // call to overridden clone method which throw an exception

   MySingletonTest t2=(MySingletonTest)t1.clone(); 
   // compiler will not reach to this line.
   System.out.println(t2); 

  } catch (CloneNotSupportedException e) {

   // TODO Auto-generated catch block

   e.printStackTrace();

  }

 }

}



Output-

Sanjaya verma

java.lang.CloneNotSupportedException

 at com.sanjay.java.interview.MySingletonTest.clone(MySingletonTest.java:21)

 at com.sanjay.java.interview.MySingletonTest.main(MySingletonTest.java:30)

Wednesday 30 November 2016

Fused location provider api example

The best thing about Fused location provider API is that you not need to worry about location updates it gives you always latest and accurate location and updates location after a interval or on location change .
One more thing about Fused location provider API is you don't need to think about best location provider because it automatically choose best one suited for your hardware of  your android device.

Now Lets start with coding. like every post i am going to make a module of our all steps to complete code.

    1. In this step we will create a new project in Android studio.
    2. we will add Google Play service in our build.gradle.
    3. In third step we will modify manifest file of our project to add location permission.
    4. we will add two TextView to our activity_main.xml to show latitude and longitude.  
    5. This will be our final step in this we will start and complete our MainAcitvity.java.

      • So lets start with coding open your Android studio and go to File-->>New Project.

                
           select an Empty Activity and left everything as default.
          • Open build.gradle(Module:app) from project explorer and add google play services to it. in simple copy below line of code and paste it under dependency of build.gradle(Module:app) like below image.

                         compile 'com.google.android.gms:play-services:8.1.0' 


            • Open manifest file and add location permission for  that you need to copy and  paste below code to your manifest file above <application tag like show in picture below.

                <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
            


            •  you need to add one more line to manifest but this will be inside <application> so just copy and   paste below code to manifest.this is version number of your gms.


            <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
            

                 Now here my manifest looks like below image.


            • Now open your activity_main.xml and add two TextView like below code.

            <?xml version="1.0" encoding="utf-8"?>
            <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingBottom="@dimen/activity_vertical_margin"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                tools:context=".MainActivity">
            
                <TextView
                    android:id="@+id/textView"
                    android:layout_margin="20dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Latitude"
                    android:layout_centerVertical="true"
                    android:layout_centerHorizontal="true" />
            
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Longitude"
                    android:id="@+id/textView2"
                    android:layout_above="@+id/textView"
                    android:layout_centerHorizontal="true" />
            
            
            </RelativeLayout>
            

            • Now open your MainActivity.java here we will implement three interface 
            1. ConnectionCallbacks
            2. OnConnectionFailedListener
            3. LocationListener

            public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
                    GoogleApiClient.OnConnectionFailedListener, LocationListener{
            

            • After implement of these three interface android studio will show you an error click on error and click on implement methods.this will implement four method to your class like below code.
             
            @Override
                public void onConnected(Bundle bundle) {
                    
                }
            
                @Override
                public void onConnectionSuspended(int i) {
            
                }
            
                @Override
                public void onLocationChanged(Location location) {
            
                }
            
                @Override
                public void onConnectionFailed(ConnectionResult connectionResult) {
            
                }
            

            • Now i am going to add two TextView, GoogleApiClient, LocationRequest, Location and two string varriable to our MainActivity.java class like below code. just copy and paste these codes above your onCreate() method.

                TextView txtOutputLat, txtOutputLon;
                Location mLastLocation;
                private GoogleApiClient mGoogleApiClient;
                private LocationRequest mLocationRequest;
                String lat,lon;
            

            • Now we will make a method to build GoogleApiClient , name of method will be buildGoogleApiClient(). in this method we will build GoogleApiClient and will add these to GoogleApiClient . 
            • OnConnectionFailedListener
            • Api(LocationServices.API)
            • ConnectionCallbacks
                  Here is my snippet of  buildGoogleApiClient().

            synchronized void buildGoogleApiClient() {
                    mGoogleApiClient = new GoogleApiClient.Builder(this)
                            .addConnectionCallbacks(this)
                            .addOnConnectionFailedListener(this)
                            .addApi(LocationServices.API)
                            .build();
            
            
                }
            

              • we also need to override onStart() and onDestroy() method of activity. in onStart() method we will connect GoogleApiClient and in onDestroy() we will disconnect it like below code.


              @Override
                  protected void onStart() {
                      super.onStart();
                      mGoogleApiClient.connect();
                  }
              
                  @Override
                  protected void onDestroy() {
                      super.onDestroy();
                      mGoogleApiClient.disconnect();
                  }
              

              • Now inside onConnected() we will create object of  LocationRequest, add priority of  accuracy  and will set interval to get location update and after that will make a request to get  last Location like below code. just copy and paste this code inside onConnected() method.in my code i am setting accuracy to High and interval is 10 second.

               mLocationRequest = LocationRequest.create();
                      mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
                      mLocationRequest.setInterval(10000); // Update location every second
              
                      LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
              
              
                      mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                              mGoogleApiClient);
                      if (mLastLocation != null) {
                          lat = String.valueOf(mLastLocation.getLatitude());
                          lon = String.valueOf(mLastLocation.getLongitude());
              
                      }
              

              • Everything is set now we are going to complete  last few step. I am going to make a method called updateUI()and in this method i will set value of latitude and longitude to  TextView and make a call of this updateUI()method in onConnected() and onLocationChange(). here is updateUI() method.

              void updateUI() {
                      txtOutputLat.setText(lat);
                      txtOutputLon.setText(lon);
                  }
              

              • we have finished all the step here is my complete MainActivity.java class.

              import android.location.Location;
              import android.support.v7.app.AppCompatActivity;
              import android.os.Bundle;
              import android.util.Log;
              import android.view.View;
              import android.widget.Button;
              import android.widget.TextView;
              
              import com.google.android.gms.common.ConnectionResult;
              import com.google.android.gms.common.api.GoogleApiClient;
              import com.google.android.gms.location.LocationListener;
              import com.google.android.gms.location.LocationRequest;
              import com.google.android.gms.location.LocationServices;
              
              public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
                      GoogleApiClient.OnConnectionFailedListener, LocationListener {
              
              
                  TextView txtOutputLat, txtOutputLon;
                  Location mLastLocation;
                  private GoogleApiClient mGoogleApiClient;
                  private LocationRequest mLocationRequest;
                  String lat, lon;
              
              
                  @Override
                  protected void onCreate(Bundle savedInstanceState) {
                      super.onCreate(savedInstanceState);
                      setContentView(R.layout.activity_main);
              
              
                      txtOutputLat = (TextView) findViewById(R.id.textView);
                      txtOutputLon = (TextView) findViewById(R.id.textView2);
              
              
                      buildGoogleApiClient();
                  }
              
              
                  @Override
                  public void onConnected(Bundle bundle) {
              
              
                      mLocationRequest = LocationRequest.create();
                      mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
                      mLocationRequest.setInterval(100); // Update location every second
              
                      LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
              
              
                      mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                              mGoogleApiClient);
                      if (mLastLocation != null) {
                          lat = String.valueOf(mLastLocation.getLatitude());
                          lon = String.valueOf(mLastLocation.getLongitude());
              
                      }
                      updateUI();
                  }
              
                  @Override
                  public void onConnectionSuspended(int i) {
              
                  }
              
                  @Override
                  public void onLocationChanged(Location location) {
                      lat = String.valueOf(location.getLatitude());
                      lon = String.valueOf(location.getLongitude());
                      updateUI();
                  }
              
                  @Override
                  public void onConnectionFailed(ConnectionResult connectionResult) {
                      buildGoogleApiClient();
                  }
              
                  synchronized void buildGoogleApiClient() {
                      mGoogleApiClient = new GoogleApiClient.Builder(this)
                              .addConnectionCallbacks(this)
                              .addOnConnectionFailedListener(this)
                              .addApi(LocationServices.API)
                              .build();
              
              
                  }
              
                  @Override
                  protected void onStart() {
                      super.onStart();
                      mGoogleApiClient.connect();
                  }
              
                  @Override
                  protected void onDestroy() {
                      super.onDestroy();
                      mGoogleApiClient.disconnect();
                  }
              
                  void updateUI() {
                      txtOutputLat.setText(lat);
                      txtOutputLon.setText(lon);
                  }
              }