What is the difference between LiveData and LifecycleObserver
Asked Answered
A

3

8

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
        }
    }

}
Autochthonous answered 25/6, 2017 at 17:8 Comment(5)
"Can I just use LiveData class ?" -- sure. LiveData has its own LifecycleObserver. There is no requirement that you implement your own.Vanden
Yes, and it brings me the question. Why do I have to use LifecycleObserver if I need to send the latest Location information from the live data. Also, I do not need to implement DB Connection, HTTP Request with LifecycleObserver because LiveData is more easy to implement. I cant figure out in what specific situation that I need to implement LifecycleObserverAutochthonous
"Why do I have to use LifecycleObserver if I need to send the latest Location information from the live data" -- you don't. "I cant figure out in what specific situation that I need to implement LifecycleObserver" -- it is there if you want to create some peer of LiveData for some other usage pattern or for integration into something else. For example, RxAndroid might leverage LifecycleObserver.Vanden
I have a new thinking about it. If the LiveData is the better pattern for the new app development. The LifecycleObserver should be treated as a bridge for the old app to migrate into the new structure. They need to remove GPS, Downloader from the onPause(), onDestory() method with implementing LifecycleObserver. As you see, the structure of MyLocationListener and LocationLiveData are very similar .Autochthonous
"Can I just use LiveData class ? because I only need to implement active and inactive function." - I think this is where the distinction is. In LiveData, you are forced to write an observer(onChange()) in the Activity for the Location data changes i.e. onChange() can have only one arg called Location. you cannot send back more information from LiveData. It is just restricted to the Location data and hence the name LiveData. Whereas in the LifecycleObserver, there is no such compulsion. Your Lifecycleobserver implementation is free to respond back to Activity in anyway.Interlocution
W
2

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.
Whisker answered 28/6, 2017 at 3:46 Comment(0)
D
2

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.

Daltondaltonism answered 25/1, 2018 at 13:32 Comment(1)
But LiveData uses a LifeCycleObserver internallyAlbaalbacete
K
1
  1. LifecycleOwner ----------> LifecycleObserver

In the above arrow diagram, no data is involved. There is a LifecyclerOwner whose Lifecycle is exposed and then there is a LifecycleObserver who will observe for the change in any LifecycleOwner's state.

  1. LifecycleOwner ----------> LiveData ------------> Observer

In the above arrow diagram, LiveData is a Data Holder which takes in the LifecycleOwner's context whose Lifecycle it should take care of and then it will emit any data change to the Observer (this Observer is not LifecycleObserver but it's a data observer) only if the LifecycleOwner is in either onStarted or onResumed state.

Katrinakatrine answered 3/6, 2019 at 12:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.