Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between LiveData and LifecycleObserver

I have read the document about Life Cycle and Live Data in the android official documentation. I know the class implemented LifeCycleObserver and make the location listener closed or open automatically. I also know the live data can make it active or inactive automatically. I have tried to implement Location Observer using these 2 ways. It works and it showed Toast 2 times when the location is updated.

My Question is , what is the difference between these 2 ways, if I really want to implement something like DB Connection, GPS Location, Download Image, running background service. Can I just use LiveData class ? because I only need to implement active and inactive function.

LocationLiveData.java

public class LocationLiveData extends LiveData<Location> {
    private LocationManager locationManager;
    private Context context;

    public LocationLiveData(Context context) {
        this.context = context;
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    }

    private LocationListener locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            setValue(location);
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

        }

        @Override
        public void onProviderEnabled(String provider) {

        }

        @Override
        public void onProviderDisabled(String provider) {

        }
    };

    @Override
    protected void onActive() {
        super.onActive();
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        locationManager.removeUpdates(locationListener);
    }
}

MyLocationListener.java

public class MyLocationListener implements LifecycleObserver {
    private LocationManager locationManager;
    private Context context;
    private LocationListener locationListener;


    public MyLocationListener(LifecycleActivity lifecycleActivity, LocationListener callback) {
        // ...
        this.context = lifecycleActivity;
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        locationListener = callback;

    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause() {
        locationManager.removeUpdates(locationListener);
    }
}

ComponentActivity.java

public class ComponentActivity extends LifecycleActivity {
    public static final int REQUEST_CODE = 200;
    private MyLocationListener myLocationListener;
    public static class MyLiveData extends ViewModel {
        private LocationLiveData locationLiveData;

        public void init(Context context) {
            locationLiveData = new LocationLiveData(context);
        }

        public LocationLiveData getLocationLiveData() {
            return locationLiveData;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_component);
//        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
//        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
                REQUEST_CODE);
        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.

        //use the live data observer
        MyLiveData myLiveData = ViewModelProviders.of(this).get(MyLiveData.class);
        myLiveData.init(this);
        myLiveData.getLocationLiveData().observe(this, new Observer<Location>() {
            @Override
            public void onChanged(@Nullable Location s) {
                Toast.makeText(ComponentActivity.this, String.format("Lat : %.2f, Lon : %.2f", s.getLongitude(), s.getLatitude()), Toast.LENGTH_SHORT).show();
            }
        });
        //use the life cycle observer
        getLifecycle().addObserver(new MyLocationListener(this, new LocationListener() {
            @Override
            public void onLocationChanged(Location s) {
                Toast.makeText(ComponentActivity.this, String.format("Lat : %.2f, Lon : %.2f", s.getLongitude(), s.getLatitude()), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {

            }

            @Override
            public void onProviderEnabled(String provider) {

            }

            @Override
            public void onProviderDisabled(String provider) {

            }
        }));


    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 200: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.

                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }
    }

}
like image 728
Long Ranger Avatar asked Jun 25 '17 17:06

Long Ranger


People also ask

Why is livedata lifecycle-aware?

As LiveData is lifecycle-aware it takes care of these things. LiveData only posts the values to Observers (activity or Fragment) if they are in a foreground state, so that no memory leaks occur. There’s no need for us to check whether View is alive or not to update the UI inside the Observer.

What is the difference between livedata and observer object?

You usually attach the Observer object in a UI controller, such as an activity or fragment. LiveData is a wrapper that can be used to hold any type of data, including objects that implement Collection s, such as List. A LiveData object is usually stored within a ViewModel object and is accessed using a getter method.

What is livedata in MVC?

The main concept of LiveData is an Observer pattern. LiveData is an observable data holder class — there’s no need to request the latest data every time. While using MVVM the communication from ViewModel to View is done with just LiveData. From the View activity or fragment we subscribe to the LiveData, passing the lifecycle owner and Observer.

How to create a livedata object with onchanged?

Create an instance of LiveData to hold a certain type of data. This is usually done inside ViewModel class. Create an Observer object that defines the onChanged () method, which controls what happens when the LiveData object's held data changes. You usually create an Observer object in a UI controller, such as an activity or fragment.


2 Answers

They are really different things which serves two separate roles. In short,

  • LifeCycle addresses the Android lifecycle problems in effective and easy ways. It has two main parts. LifecycleOwner exposes its state changes, and LifecycleObserver listens to these changes to make appropriate steps.
  • LiveData, on the other hand, leverages reactive programming which helps us manipulate data easily. It shares some similarities with Stream in Java 8 and Observer(or Flowable) in RxJava. However, LiveData has an advantage is that it is lifecycle-aware specific for Android. So, it works closely with LifeCycle components.
like image 65
Quang Nguyen Avatar answered Oct 09 '22 13:10

Quang Nguyen


From a higher abstraction level, I think that:

  • LiveData is a data holder which host some data, with the difference that it's LifeCycle Aware. So it's an observable data holder, not an observer!
  • LifecycleObserver on the other hand is an observer who cares about lifecycles.

I believe that is the main distinction.

like image 25
Themelis Avatar answered Oct 09 '22 15:10

Themelis